<?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>Til on Haseeb Majid</title>
    <link>https://haseebmajid.dev/series/til/</link>
    <description>Recent content in Til on Haseeb Majid</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Mon, 09 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://haseebmajid.dev/series/til/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>TIL - How to Git Push to Multiple Repositories</title>
      <link>https://haseebmajid.dev/posts/2026-03-09-til-how-to-git-push-to-multiple-repositories/</link>
      <pubDate>Mon, 09 Mar 2026 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2026-03-09-til-how-to-git-push-to-multiple-repositories/</guid>
      <description>&lt;p&gt;I have a personal project that I wanted to push to both tangled.sh (self-hosted) and GitLab. In case something
happened to my personal homelab and backups.&lt;/p&gt;
&lt;p&gt;You can do this but adding another remote i.e. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git remote set-url --add --push origin git@gitlab.com:hmajid2301/go-routinely.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Make sure to add both repositories with this command&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then when you go git push it will push to all repositories.&lt;/p&gt;
&lt;p&gt;You can double check with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goroutinely on  fix/ci &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;$&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; via 🐹 v1.25.5 via ❄  impure &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;nix-shell-env&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;❯ git remote show origin
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Welcome to this knot!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;* remote origin
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Fetch URL: git@git.haseebmajid.dev:majiy00.tngl.sh/go-routinely
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Push  URL: git@git.haseebmajid.dev:majiy00.tngl.sh/go-routinely
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Push  URL: git@gitlab.com:hmajid2301/go-routinely.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  HEAD branch: main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/14290113/git-pushing-code-to-two-remotes&#34;&gt;https://stackoverflow.com/questions/14290113/git-pushing-code-to-two-remotes&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I have a personal project that I wanted to push to both tangled.sh (self-hosted) and GitLab. In case something
happened to my personal homelab and backups.</p>
<p>You can do this but adding another remote i.e. <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git remote set-url --add --push origin git@gitlab.com:hmajid2301/go-routinely.git
</span></span></code></pre></div><blockquote>
<p>Make sure to add both repositories with this command</p>
</blockquote>
<p>Then when you go git push it will push to all repositories.</p>
<p>You can double check with:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">goroutinely on  fix/ci <span class="o">[</span>$<span class="o">]</span> via 🐹 v1.25.5 via ❄  impure <span class="o">(</span>nix-shell-env<span class="o">)</span>
</span></span><span class="line"><span class="cl">❯ git remote show origin
</span></span><span class="line"><span class="cl">Welcome to this knot!
</span></span><span class="line"><span class="cl">* remote origin
</span></span><span class="line"><span class="cl">  Fetch URL: git@git.haseebmajid.dev:majiy00.tngl.sh/go-routinely
</span></span><span class="line"><span class="cl">  Push  URL: git@git.haseebmajid.dev:majiy00.tngl.sh/go-routinely
</span></span><span class="line"><span class="cl">  Push  URL: git@gitlab.com:hmajid2301/go-routinely.git
</span></span><span class="line"><span class="cl">  HEAD branch: main
</span></span></code></pre></div><div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://stackoverflow.com/questions/14290113/git-pushing-code-to-two-remotes">https://stackoverflow.com/questions/14290113/git-pushing-code-to-two-remotes</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL - How to Fix Tailscale Using Mullvad as Exit Nodes on NixOS</title>
      <link>https://haseebmajid.dev/posts/2025-12-29-til-how-to-fix-tailscale-using-mullvad-as-exit-nodes-on-nixos/</link>
      <pubDate>Mon, 29 Dec 2025 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2025-12-29-til-how-to-fix-tailscale-using-mullvad-as-exit-nodes-on-nixos/</guid>
      <description>&lt;p&gt;On NixOS when ever I enabled &lt;a href=&#34;https://tailscale.com/kb/1258/mullvad-exit-nodes&#34;&gt;mullvad&lt;/a&gt; as exit nodes via tailscale (the &lt;a href=&#34;https://github.com/DeedleFake/trayscale&#34;&gt;trayscale app&lt;/a&gt;).
My internet would stop working, which was weird as this worked fine on my other devices i.e. Ubuntu or my phone.&lt;/p&gt;
&lt;p&gt;Well turns out it seems to be the way NixOS works with the firewall, you can read all the details here &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Where
the poster explains it really well.&lt;/p&gt;
&lt;p&gt;My understanding is the following:&lt;/p&gt;
&lt;p&gt;This changes RPF (reverse path filtering) from &amp;ldquo;strict&amp;rdquo; to &amp;ldquo;loose&amp;rdquo; mode:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>On NixOS when ever I enabled <a href="https://tailscale.com/kb/1258/mullvad-exit-nodes">mullvad</a> as exit nodes via tailscale (the <a href="https://github.com/DeedleFake/trayscale">trayscale app</a>).
My internet would stop working, which was weird as this worked fine on my other devices i.e. Ubuntu or my phone.</p>
<p>Well turns out it seems to be the way NixOS works with the firewall, you can read all the details here <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. Where
the poster explains it really well.</p>
<p>My understanding is the following:</p>
<p>This changes RPF (reverse path filtering) from &ldquo;strict&rdquo; to &ldquo;loose&rdquo; mode:</p>
<ul>
<li>Strict: Reply must go back out the exact same interface it came in on</li>
<li>Loose: Reply can go out any interface, as long as there&rsquo;s a valid route back to the source</li>
</ul>
<h2 id="solution">Solution</h2>
<p>But the fix is enabling this option: <code>networking.firewall.checkReversePath = &quot;loose&quot;;</code>. Please make sure you understand
exactly what you are doing when enabling this.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://github.com/tailscale/tailscale/issues/4432#issuecomment-1112819111">https://github.com/tailscale/tailscale/issues/4432#issuecomment-1112819111</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL - How to Fix App Lounge Updates Getting Stuck (MurenaOS/eOS)</title>
      <link>https://haseebmajid.dev/posts/2025-12-28-til-how-to-fix-app-lounge-updates-getting-stuck-murenaos-eos-/</link>
      <pubDate>Sun, 28 Dec 2025 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2025-12-28-til-how-to-fix-app-lounge-updates-getting-stuck-murenaos-eos-/</guid>
      <description>&lt;p&gt;If you use a FairPhone, or a phone running &lt;a href=&#34;https://e.foundation/e-os/&#34;&gt;eOS/MurenaOS&lt;/a&gt;, which is as degoogled version of
Android (no affiliation to me besides I use their devices/OS).&lt;/p&gt;
&lt;p&gt;Sometimes the app store &amp;ldquo;App Lounge&amp;rdquo; gets stuck updating apps, my old solution was to delete the app and reinstall it
but that can be a pain. Then I discovered a slightly better solution.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to settings&lt;/li&gt;
&lt;li&gt;Apps &amp;amp; Notifications&lt;/li&gt;
&lt;li&gt;Find App Lounge&lt;/li&gt;
&lt;li&gt;Then go to Storage &amp;amp; cache&lt;/li&gt;
&lt;li&gt;Clear storage and &amp;ldquo;Delete app data&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You will need to log in again to the app, but the update process shouldn&amp;rsquo;t get stuck anymore hopefully.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>If you use a FairPhone, or a phone running <a href="https://e.foundation/e-os/">eOS/MurenaOS</a>, which is as degoogled version of
Android (no affiliation to me besides I use their devices/OS).</p>
<p>Sometimes the app store &ldquo;App Lounge&rdquo; gets stuck updating apps, my old solution was to delete the app and reinstall it
but that can be a pain. Then I discovered a slightly better solution.</p>
<ul>
<li>Go to settings</li>
<li>Apps &amp; Notifications</li>
<li>Find App Lounge</li>
<li>Then go to Storage &amp; cache</li>
<li>Clear storage and &ldquo;Delete app data&rdquo;</li>
</ul>
<p>You will need to log in again to the app, but the update process shouldn&rsquo;t get stuck anymore hopefully.</p>
<p>[^1] <a href="https://community.e.foundation/t/applounge-updates-stuck/47296/11">https://community.e.foundation/t/applounge-updates-stuck/47296/11</a></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL - How to Enable Video Thumbnails for SMB Share on Nixos and Nautilus</title>
      <link>https://haseebmajid.dev/posts/2025-11-06-til-how-to-enable-video-thumbnails-for-smb-share-on-nixos/</link>
      <pubDate>Thu, 06 Nov 2025 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2025-11-06-til-how-to-enable-video-thumbnails-for-smb-share-on-nixos/</guid>
      <description>&lt;p&gt;So recently I have setup a mini NAS and I connect to it via an SMB share, but on nautilus I noticed that
unlike my local files for the videos it would not create thumbnails when I was using nautilus (file manager for Gnome).&lt;/p&gt;
&lt;p&gt;The fix ended up being pretty simple &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Nautilus &amp;gt; Preference &amp;gt; Show thumbnails.

Set it to &amp;#34;On this computer only&amp;#34; for only seeing thumbnails on your system, .

If u need it to do same for a remote server, select &amp;#34;All files&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or since we are managing this via NixOS and want to do things declaratively we can do do the following in our Nix config &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>So recently I have setup a mini NAS and I connect to it via an SMB share, but on nautilus I noticed that
unlike my local files for the videos it would not create thumbnails when I was using nautilus (file manager for Gnome).</p>
<p>The fix ended up being pretty simple <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>:</p>
<pre tabindex="0"><code>Nautilus &gt; Preference &gt; Show thumbnails.

Set it to &#34;On this computer only&#34; for only seeing thumbnails on your system, .

If u need it to do same for a remote server, select &#34;All files&#34;
</code></pre><p>Or since we are managing this via NixOS and want to do things declaratively we can do do the following in our Nix config <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="n">dconf</span><span class="o">.</span><span class="n">settings</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;org/gnome/nautilus/preferences&#34;</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">show-image-thumbnails</span> <span class="o">=</span> <span class="s2">&#34;always&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>That&rsquo;s it, in your SMB share you should now be able to view thumbnails for all of your videos.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://www.reddit.com/r/gnome/comments/u6t0u8/comment/i5aq8no/?utm_source=share&amp;utm_medium=web3x&amp;utm_name=web3xcss&amp;utm_term=1&amp;utm_content=share_button">https://www.reddit.com/r/gnome/comments/u6t0u8/comment/i5aq8no/?utm_source=share&amp;utm_medium=web3x&amp;utm_name=web3xcss&amp;utm_term=1&amp;utm_content=share_button</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><a href="https://gitlab.com/hmajid2301/nixicle/-/blob/changes/modules/nixos/roles/desktop/addons/nautilus/default.nix">https://gitlab.com/hmajid2301/nixicle/-/blob/changes/modules/nixos/roles/desktop/addons/nautilus/default.nix</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL - How to Change Emojis in nh</title>
      <link>https://haseebmajid.dev/posts/2025-08-10-til-how-to-change-emojis-in-nh/</link>
      <pubDate>Sun, 10 Aug 2025 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2025-08-10-til-how-to-change-emojis-in-nh/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL - How to Change Emojis in nh&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I have been trying to update the emojis when I run &lt;a href=&#34;https://github.com/nix-community/nh&#34;&gt;nh&lt;/a&gt;. Particularly
the nom output.&lt;/p&gt;
&lt;p&gt;The old output was like so:&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2025-08-10-til-how-to-change-emojis-in-nh/images/old_emoji.png&#34;
        type=&#34;&#34;
        alt=&#34;old nom nh&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;To fix this update your nh derivation like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;systemPackages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pkgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pkgs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nh&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;override&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nix-output-monitor&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pkgs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nix-output-monitor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;overrideAttrs&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;postPatch&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;postPatch&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        substituteInPlace lib/NOM/Print.hs \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;down = &amp;#34;↓&amp;#34;&amp;#39; &amp;#39;down = &amp;#34;\xf072e&amp;#34;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;up = &amp;#34;↑&amp;#34;&amp;#39; &amp;#39;up = &amp;#34;\xf0737&amp;#34;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;clock = &amp;#34;⏱&amp;#34;&amp;#39; &amp;#39;clock = &amp;#34;\xf520&amp;#34;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;running = &amp;#34;⏵&amp;#34;&amp;#39; &amp;#39;running = &amp;#34;\xf04b&amp;#34;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;done = &amp;#34;✔&amp;#34;&amp;#39; &amp;#39;done = &amp;#34;\xf00c&amp;#34;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;todo = &amp;#34;⏸&amp;#34;&amp;#39; &amp;#39;todo = &amp;#34;\xf04d&amp;#34;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;warning = &amp;#34;⚠&amp;#34;&amp;#39; &amp;#39;warning = &amp;#34;\xf071&amp;#34;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;average = &amp;#34;∅&amp;#34;&amp;#39; &amp;#39;average = &amp;#34;\xf1da&amp;#34;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;          --replace &amp;#39;bigsum = &amp;#34;∑&amp;#34;&amp;#39; &amp;#39;bigsum = &amp;#34;\xf04a0&amp;#34;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;      &amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note you will no longer be able to use the default nix cache to build this. So everytime nh updates you will need to
manually build it.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL - How to Change Emojis in nh</strong></p>
<p>Recently I have been trying to update the emojis when I run <a href="https://github.com/nix-community/nh">nh</a>. Particularly
the nom output.</p>
<p>The old output was like so:</p>
<p><img
        loading="lazy"
        src="/posts/2025-08-10-til-how-to-change-emojis-in-nh/images/old_emoji.png"
        type=""
        alt="old nom nh"
        
      /></p>
<p>To fix this update your nh derivation like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">environment</span><span class="o">.</span><span class="n">systemPackages</span> <span class="o">=</span> <span class="k">with</span> <span class="n">pkgs</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="n">pkgs</span><span class="o">.</span><span class="n">nh</span><span class="o">.</span><span class="n">override</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">nix-output-monitor</span> <span class="o">=</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">nix-output-monitor</span><span class="o">.</span><span class="n">overrideAttrs</span> <span class="p">(</span><span class="n">old</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">postPatch</span> <span class="o">=</span> <span class="n">old</span><span class="o">.</span><span class="n">postPatch</span> <span class="n">or</span> <span class="s2">&#34;&#34;</span> <span class="o">+</span> <span class="s1">&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">        substituteInPlace lib/NOM/Print.hs \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;down = &#34;↓&#34;&#39; &#39;down = &#34;\xf072e&#34;&#39; \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;up = &#34;↑&#34;&#39; &#39;up = &#34;\xf0737&#34;&#39; \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;clock = &#34;⏱&#34;&#39; &#39;clock = &#34;\xf520&#34;&#39; \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;running = &#34;⏵&#34;&#39; &#39;running = &#34;\xf04b&#34;&#39; \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;done = &#34;✔&#34;&#39; &#39;done = &#34;\xf00c&#34;&#39; \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;todo = &#34;⏸&#34;&#39; &#39;todo = &#34;\xf04d&#34;&#39; \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;warning = &#34;⚠&#34;&#39; &#39;warning = &#34;\xf071&#34;&#39; \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;average = &#34;∅&#34;&#39; &#39;average = &#34;\xf1da&#34;&#39; \
</span></span></span><span class="line"><span class="cl"><span class="s1">          --replace &#39;bigsum = &#34;∑&#34;&#39; &#39;bigsum = &#34;\xf04a0&#34;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">      &#39;&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span></code></pre></div><p>Note you will no longer be able to use the default nix cache to build this. So everytime nh updates you will need to
manually build it.</p>
<p><img
        loading="lazy"
        src="/posts/2025-08-10-til-how-to-change-emojis-in-nh/images/new_emoji.png"
        type=""
        alt="new nom nh"
        
      /></p>
<p>That&rsquo;s it!</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL - How to Set Dynamic URL With HTMX and AlpineJS</title>
      <link>https://haseebmajid.dev/posts/2025-04-29-til-set-dynamic-url-with-htmx-and-alpinejs/</link>
      <pubDate>Tue, 29 Apr 2025 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2025-04-29-til-set-dynamic-url-with-htmx-and-alpinejs/</guid>
      <description>&lt;p&gt;TLDR; Add this attribute to your x-bind:hx-delete &lt;code&gt;x-effect=&amp;quot;currentItemId;htmx.process($el)&amp;quot;&lt;/code&gt; as an example (adjust for your example).&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;In my app, I show the user 25 feedbacks per page, and they can delete them which opens a modal to confirm the action.
If the user presses the delete button in the modal I want to send a HTTP DELETE request to an endpoint like
&lt;code&gt;/feedback/{id}&lt;/code&gt;, but the ID is dynamic, as we are using one modal for all the feedbacks vs having one modal
per one feedback.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>TLDR; Add this attribute to your x-bind:hx-delete <code>x-effect=&quot;currentItemId;htmx.process($el)&quot;</code> as an example (adjust for your example).</p>
<h2 id="background">Background</h2>
<p>In my app, I show the user 25 feedbacks per page, and they can delete them which opens a modal to confirm the action.
If the user presses the delete button in the modal I want to send a HTTP DELETE request to an endpoint like
<code>/feedback/{id}</code>, but the ID is dynamic, as we are using one modal for all the feedbacks vs having one modal
per one feedback.</p>
<p>I am using HTMX, generated using templ and using AlpineJS for some frontend interactivity, where it doesn&rsquo;t make
sense to send a request back to the server.</p>
<h2 id="solution">Solution</h2>
<p>The solution is relatively easily in the end</p>
<p>We have a button like this which triggers the modal to open, this is rendered in templ via Go. Hence the <code>fmt.Sprintf</code>
function. Here we are setting a variable which will be used by AlpineJS.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;btn btn-ghost btn-xs text-neutral&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">@</span><span class="na">click</span><span class="o">=</span><span class="s">{</span> <span class="na">fmt</span><span class="err">.</span><span class="na">Sprintf</span><span class="err">(&#34;</span><span class="na">currentItemId </span><span class="o">=</span> <span class="s">&#39;%s&#39;</span><span class="err">;</span> <span class="na">document</span><span class="err">.</span><span class="na">getElementById</span><span class="err">(&#39;</span><span class="na">delete-modal</span><span class="err">&#39;).</span><span class="na">showModal</span><span class="err">()&#34;,</span> <span class="na">item</span><span class="err">.</span><span class="na">ID</span><span class="err">)</span> <span class="err">}</span>
</span></span><span class="line"><span class="cl">    <span class="na">aria-label</span><span class="o">=</span><span class="s">&#34;Delete Feedback&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;text-lg hgi hgi-solid hgi-delete-02&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">i</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>In one of the parent div make sure we set the <code>x-data</code> attribute, which matches the same variable we set on the <code>@click</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;&#34;</span> <span class="na">x-data</span><span class="o">=</span><span class="s">&#34;{ currentItemId: &#39;&#39; }&#34;</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Finally here is a simplified version of the button in the modal when pressed will send the delete request.
The key line is <code>x-effect=&quot;currentItemId;htmx.process($el)&quot;</code>, we need HTMX to reevaluate the hx-delete attribute.
Else the request will go to <code>/feedback/</code> without the ID.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="na">x-bind:hx-delete</span><span class="o">=</span><span class="s">&#34;&#39;/feedback/&#39; + currentItemId&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">x-effect</span><span class="o">=</span><span class="s">&#34;currentItemId;htmx.process($el)&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">hx-target</span><span class="o">=</span><span class="s">&#34;#feedback_list&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">hx-swap</span><span class="o">=</span><span class="s">&#34;outerHTML&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Delete
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>That&rsquo;s it, now you can set the endpoint dynamically, generally speaking I don&rsquo;t need to use this pattern much.
As most of the time this can be set when we render the template as they are usually static.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li>Github: <a href="https://github.com/mvolkmann/htmx-examples/blob/main/dynamic-endpoint/public/index.html">https://github.com/mvolkmann/htmx-examples/blob/main/dynamic-endpoint/public/index.html</a></li>
<li>Reddit Post: <a href="https://old.reddit.com/r/htmx/comments/1fyaw8r/htmx_and_alpinejs_dynamic_data/">https://old.reddit.com/r/htmx/comments/1fyaw8r/htmx_and_alpinejs_dynamic_data/</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL - Fix Telescope Ignoring Env Files</title>
      <link>https://haseebmajid.dev/posts/2025-04-28-til-fix-telescope-ignoring-env-files/</link>
      <pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2025-04-28-til-fix-telescope-ignoring-env-files/</guid>
      <description>&lt;p&gt;Recently I noticed when I searched using Telescope in Neovim, that I could see &lt;code&gt;env.local.template&lt;/code&gt; but not
&lt;code&gt;.env.local&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Where my keybinding looked like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;vim.keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;lt;leader&amp;gt;ff&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;builtin.find_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hidden&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;follow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Find all files&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This was because I was ignoring the &lt;code&gt;.env*&lt;/code&gt; paths in my gitignore, I could tell telescope to not follow the gitignore.
But I would get a lot more junk when searching in Telescope. I just wanted to see certain patterns but still
mostly respect the gitignore file. You can do the following:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Recently I noticed when I searched using Telescope in Neovim, that I could see <code>env.local.template</code> but not
<code>.env.local</code>.</p>
<p>Where my keybinding looked like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;leader&gt;ff&#34;</span><span class="p">,</span> <span class="kr">function</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">builtin.find_files</span><span class="p">({</span> <span class="n">hidden</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="n">follow</span> <span class="o">=</span> <span class="kc">true</span> <span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="kr">end</span><span class="p">,</span> <span class="p">{</span> <span class="n">desc</span> <span class="o">=</span> <span class="s2">&#34;Find all files&#34;</span> <span class="p">})</span>
</span></span></code></pre></div><p>This was because I was ignoring the <code>.env*</code> paths in my gitignore, I could tell telescope to not follow the gitignore.
But I would get a lot more junk when searching in Telescope. I just wanted to see certain patterns but still
mostly respect the gitignore file. You can do the following:</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">#  create a ~/.ignore file</span>
</span></span><span class="line"><span class="cl">nvim ~/.ignore
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Mine looks like this</span>
</span></span><span class="line"><span class="cl">!.env.local
</span></span><span class="line"><span class="cl">!*/.env.local
</span></span><span class="line"><span class="cl">!.env.test
</span></span><span class="line"><span class="cl">!*/.env.test
</span></span></code></pre></div><p>Now in Telescope the <code>.env.local</code> and <code>.env.test</code> files are searchable. But still ignored by git I don&rsquo;t want to commit
them as they contain secrets.</p>
<p>This of course assumes you are using ripgrep to do the search, in my config I have the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">vimgrep_arguments</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;rg&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;-L&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--color=never&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--no-heading&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--with-filename&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--line-number&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--column&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--smart-case&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--fixed-strings&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span></code></pre></div><p>GitHub Issue: <a href="https://github.com/LunarVim/LunarVim/discussions/3770#discussioncomment-11523524">https://github.com/LunarVim/LunarVim/discussions/3770#discussioncomment-11523524</a></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL - How to Get Dropbar and Auto Session to Work</title>
      <link>https://haseebmajid.dev/posts/2025-04-12-til-how-to-get-dropbar-and-auto-session-to-work/</link>
      <pubDate>Sat, 12 Apr 2025 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2025-04-12-til-how-to-get-dropbar-and-auto-session-to-work/</guid>
      <description>&lt;details
  class=&#34;notice info&#34;
  open=&#34;true&#34;
&gt;
    &lt;summary class=&#34;notice-title&#34;&gt;Original Article&lt;/summary&gt;
  
  You can find more context on the problem &lt;a href=&#34;../../posts/2025-03-22-til-fix-issue-with-dropbar-and-auto-session&#34;&gt;here&lt;/a&gt;
&lt;/details&gt;

&lt;p&gt;In my post last month I thought I had fixed this issue but turns out I did not. The actual fix to stop getting
this error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;5108: Error executing lua &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;string &lt;span class=&#34;s2&#34;&gt;&amp;#34;v:lua&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;:1: attempt to call global &lt;span class=&#34;s1&#34;&gt;&amp;#39;dropbar&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;a nil value&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;stack traceback:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;string &lt;span class=&#34;s2&#34;&gt;&amp;#34;v:lua&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;:1: in main chunk
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bat /home/haseeb/.local/share/nixCats-nvim/sessions/%2Fhome%2Fhaseeb%2Fprojects%2Fvoxicle.vim &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; rg dropbar
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;setlocal &lt;span class=&#34;nv&#34;&gt;winbar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;%&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;%v:lua.dropbar&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;%&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;setlocal &lt;span class=&#34;nv&#34;&gt;winbar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;%&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;%v:lua.dropbar&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;%&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;setlocal &lt;span class=&#34;nv&#34;&gt;winbar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;%&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;%v:lua.dropbar&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;%&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We want the winbar to nil. The fix that worked for me was this:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<details
  class="notice info"
  open="true"
>
    <summary class="notice-title">Original Article</summary>
  
  You can find more context on the problem <a href="/posts/2025-03-22-til-fix-issue-with-dropbar-and-auto-session">here</a>
</details>

<p>In my post last month I thought I had fixed this issue but turns out I did not. The actual fix to stop getting
this error:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">5108: Error executing lua <span class="o">[</span>string <span class="s2">&#34;v:lua&#34;</span><span class="o">]</span>:1: attempt to call global <span class="s1">&#39;dropbar&#39;</span> <span class="o">(</span>a nil value<span class="o">)</span>
</span></span><span class="line"><span class="cl">stack traceback:
</span></span><span class="line"><span class="cl">        <span class="o">[</span>string <span class="s2">&#34;v:lua&#34;</span><span class="o">]</span>:1: in main chunk
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">bat /home/haseeb/.local/share/nixCats-nvim/sessions/%2Fhome%2Fhaseeb%2Fprojects%2Fvoxicle.vim <span class="p">|</span> rg dropbar
</span></span><span class="line"><span class="cl">setlocal <span class="nv">winbar</span><span class="o">=</span>%<span class="o">{</span>%v:lua.dropbar<span class="o">()</span>%<span class="o">}</span>
</span></span><span class="line"><span class="cl">setlocal <span class="nv">winbar</span><span class="o">=</span>%<span class="o">{</span>%v:lua.dropbar<span class="o">()</span>%<span class="o">}</span>
</span></span><span class="line"><span class="cl">setlocal <span class="nv">winbar</span><span class="o">=</span>%<span class="o">{</span>%v:lua.dropbar<span class="o">()</span>%<span class="o">}</span>
</span></span></code></pre></div><p>We want the winbar to nil. The fix that worked for me was this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">vim.o</span><span class="p">.</span><span class="n">sessionoptions</span> <span class="o">=</span> <span class="s2">&#34;blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal,localoptions&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">require</span><span class="p">(</span><span class="s2">&#34;auto-session&#34;</span><span class="p">).</span><span class="n">setup</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">	<span class="n">pre_save_cmds</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="kr">function</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">			<span class="n">vim.cmd</span><span class="p">(</span><span class="s">[[
</span></span></span><span class="line"><span class="cl"><span class="s">                noautocmd windo set winbar=
</span></span></span><span class="line"><span class="cl"><span class="s">                noautocmd windo setlocal winbar=
</span></span></span><span class="line"><span class="cl"><span class="s">            ]]</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="kr">end</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix Issue With Dropbar and Auto Session</title>
      <link>https://haseebmajid.dev/posts/2025-03-22-til-fix-issue-with-dropbar-and-auto-session/</link>
      <pubDate>Sat, 22 Mar 2025 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2025-03-22-til-fix-issue-with-dropbar-and-auto-session/</guid>
      <description>&lt;details
  class=&#34;notice danger&#34;
  open=&#34;true&#34;
&gt;
    &lt;summary class=&#34;notice-title&#34;&gt;Actual Fix&lt;/summary&gt;
  
  This fix didn&amp;rsquo;t actually work the actual fix can be found &lt;a href=&#34;../../posts/2025-04-12-til-how-to-get-dropbar-and-auto-session-to-work&#34;&gt;here&lt;/a&gt;
&lt;/details&gt;

&lt;p&gt;I recently moved to &lt;a href=&#34;https://github.com/Bekaboo/dropbar.nvim&#34;&gt;dropbar&lt;/a&gt; from barbecue as it has been archived and kept
getting a weird error for buffer open when I would reopen Neovim. I use the &lt;a href=&#34;https://github.com/rmagatti/auto-session&#34;&gt;auto-session plugin&lt;/a&gt;,
which loads back the previous state of NixVim when I last exited in that folder, i.e. open buffers.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;E5108&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;executing&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lua&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;v:lua&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attempt&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;call&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;global&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;dropbar&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;stack&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;traceback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;v:lua&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chunk&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I noticed though I would only get this error the second time I would open Neovim, which then made think maybe it was
an issue with auto-session. So I looked at the serialised file it generates so it knows what to load when we open
Neovim again. Which I found at:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<details
  class="notice danger"
  open="true"
>
    <summary class="notice-title">Actual Fix</summary>
  
  This fix didn&rsquo;t actually work the actual fix can be found <a href="/posts/2025-04-12-til-how-to-get-dropbar-and-auto-session-to-work">here</a>
</details>

<p>I recently moved to <a href="https://github.com/Bekaboo/dropbar.nvim">dropbar</a> from barbecue as it has been archived and kept
getting a weird error for buffer open when I would reopen Neovim. I use the <a href="https://github.com/rmagatti/auto-session">auto-session plugin</a>,
which loads back the previous state of NixVim when I last exited in that folder, i.e. open buffers.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">E5108</span><span class="p">:</span> <span class="n">Error</span> <span class="n">executing</span> <span class="n">lua</span> <span class="p">[</span><span class="n">string</span> <span class="s2">&#34;v:lua&#34;</span><span class="p">]:</span><span class="mi">1</span><span class="p">:</span> <span class="n">attempt</span> <span class="n">to</span> <span class="n">call</span> <span class="n">global</span> <span class="s1">&#39;dropbar&#39;</span> <span class="p">(</span><span class="n">a</span> <span class="kc">nil</span> <span class="n">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">stack</span> <span class="n">traceback</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="p">[</span><span class="n">string</span> <span class="s2">&#34;v:lua&#34;</span><span class="p">]:</span><span class="mi">1</span><span class="p">:</span> <span class="kr">in</span> <span class="n">main</span> <span class="n">chunk</span>
</span></span></code></pre></div><p>I noticed though I would only get this error the second time I would open Neovim, which then made think maybe it was
an issue with auto-session. So I looked at the serialised file it generates so it knows what to load when we open
Neovim again. Which I found at:</p>
<p><code>nvim /home/haseeb/.local/share/nvim/sessions/%2Fhome%2Fhaseeb%2Fprojects%2Fvoxicle.vim</code></p>
<p>One line in there looked like this:</p>
<p><code>setlocal winbar=%{%v:lua.dropbar()%}</code></p>
<p>So I removed this line by updating my config:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">require</span><span class="p">(</span><span class="s2">&#34;auto-session&#34;</span><span class="p">).</span><span class="n">setup</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">	<span class="n">pre_save_cmds</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="kr">function</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">			<span class="n">vim.opt</span><span class="p">.</span><span class="n">winbar</span> <span class="o">=</span> <span class="kc">nil</span> <span class="c1">-- Clear winbar before saving session</span>
</span></span><span class="line"><span class="cl">		<span class="kr">end</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p>This stopped the error from occurring, as there is no winbar line now. I am not a 100% what was happening, but it seems
it was running this line before dropbar had loaded. I am using <a href="https://github.com/BirdeeHub/nixCats-nvim">nixCats</a>.
Anyway, that&rsquo;s it! That should resolve the issues.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Cancel Stale Pipelines in GitLab CI</title>
      <link>https://haseebmajid.dev/posts/2024-09-15-til-how-to-cancel-stale-pipelines-in-gitlab-ci/</link>
      <pubDate>Sun, 15 Sep 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-09-15-til-how-to-cancel-stale-pipelines-in-gitlab-ci/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Cancel Stale Pipelines in GitLab CI&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Today I learnt that we can cancel old pipelines in MRs. For example, you push a new commit, and you don&amp;rsquo;t care about the
old pipeline running any more. You want to cancel them to save CI minutes etc.&lt;/p&gt;
&lt;p&gt;Here is an example, you can see the 2nd pipeline is cancelled:&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2024-09-15-til-how-to-cancel-stale-pipelines-in-gitlab-ci/images/gitlab-ci-cancelled.png&#34;
        type=&#34;&#34;
        alt=&#34;gitlab-ci-cancelled.png&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;We need to add this to our &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file. Where the &lt;code&gt;default.interruptible&lt;/code&gt; marks every job as it can be
cancelled &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Cancel Stale Pipelines in GitLab CI</strong></p>
<p>Today I learnt that we can cancel old pipelines in MRs. For example, you push a new commit, and you don&rsquo;t care about the
old pipeline running any more. You want to cancel them to save CI minutes etc.</p>
<p>Here is an example, you can see the 2nd pipeline is cancelled:</p>
<p><img
        loading="lazy"
        src="/posts/2024-09-15-til-how-to-cancel-stale-pipelines-in-gitlab-ci/images/gitlab-ci-cancelled.png"
        type=""
        alt="gitlab-ci-cancelled.png"
        
      /></p>
<p>We need to add this to our <code>.gitlab-ci.yml</code> file. Where the <code>default.interruptible</code> marks every job as it can be
cancelled <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">workflow</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">auto_cancel</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">on_new_commit</span><span class="p">:</span><span class="w"> </span><span class="l">interruptible</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="nt">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">interruptible</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span></code></pre></div><p>Then on new commits, we cancel all interruptible jobs. Just make sure to be careful where jobs actually deploy stuff.
You don&rsquo;t want to partially deploy things. But for jobs like running tests, linting etc this should be all good.</p>
<ul>
<li><a href="https://gitlab.com/hmajid2301/banterbus/-/blob/1ef5ae17e81b75576d7df02a60c9e95e11fc6d96/.gitlab-ci.yml">Example gitlab pipeline</a></li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://docs.gitlab.com/ee/ci/yaml/index.html#interruptible##">https://docs.gitlab.com/ee/ci/yaml/index.html#interruptible##</a> Appendix&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Get Shell Completions in Nix Shell With Direnv</title>
      <link>https://haseebmajid.dev/posts/2024-09-12-til-how-to-get-shell-completions-in-nix-shell-with-direnv/</link>
      <pubDate>Thu, 12 Sep 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-09-12-til-how-to-get-shell-completions-in-nix-shell-with-direnv/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Get Shell Completions in Nix Shell With Direnv&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When shell completions don&amp;rsquo;t work with direnv, you may need to use &lt;code&gt;nix develop&lt;/code&gt; to load the shell manually.&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;I am using &lt;code&gt;nix-direnv&lt;/code&gt;, with nix devshell to autoload into my development environments. I changed the directory
and the devshell is automagically loaded without me doing anything, which is great. Provides me with a bunch of tools
specific for that project. With all the benefits of Nix, mainly reproducibility.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Get Shell Completions in Nix Shell With Direnv</strong></p>
<p>When shell completions don&rsquo;t work with direnv, you may need to use <code>nix develop</code> to load the shell manually.</p>
<h2 id="background">Background</h2>
<p>I am using <code>nix-direnv</code>, with nix devshell to autoload into my development environments. I changed the directory
and the devshell is automagically loaded without me doing anything, which is great. Provides me with a bunch of tools
specific for that project. With all the benefits of Nix, mainly reproducibility.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ z banterbus/
</span></span><span class="line"><span class="cl">direnv: loading ~/projects/banterbus/.envrc
</span></span><span class="line"><span class="cl">direnv: using flake
</span></span><span class="line"><span class="cl">direnv: nix-direnv: Using cached dev shell
</span></span><span class="line"><span class="cl">direnv: <span class="nb">export</span> +AR +AS +CC +CONFIG_SHELL +CXX +GOTOOLDIR +HOST_PATH +IN_NIX_SHELL +LD +NIX_BINTOOLS +NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_BUILD_CORES +NIX_CC +NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_CFLAGS_COMPILE +NIX_ENFORCE_NO_NATIVE +NIX_HARDENING_ENABLE +NIX_LDFLAGS +NIX_STORE +NM +OBJCOPY +OBJDUMP +PLAYWRIGHT_BROWSERS_PATH +PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD +RANLIB +READELF +SIZE +SOURCE_DATE_EPOCH +STRINGS +STRIP +__structuredAttrs +buildInputs +buildPhase +builder +cmakeFlags +configureFlags +depsBuildBuild +depsBuildBuildPropagated +depsBuildTarget +depsBuildTargetPropagated +depsHostHost +depsHostHostPropagated +depsTargetTarget +depsTargetTargetPropagated +doCheck +doInstallCheck +dontAddDisableDepTrack +hardeningDisable +mesonFlags +name +nativeBuildInputs +out +outputs +patches +phases +preferLocalBuild +propagatedBuildInputs +propagatedNativeBuildInputs +shell +shellHook +stdenv +strictDeps +system ~PATH ~XDG_DATA_DIRS
</span></span></code></pre></div><p>Where my mkShell function looks something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">pkgs</span><span class="o">.</span><span class="n">mkShell</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">hardeningDisable</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;all&#34;</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="n">shellHook</span> <span class="o">=</span> <span class="s1">&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">      export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
</span></span></span><span class="line"><span class="cl"><span class="s1">      export PLAYWRIGHT_BROWSERS_PATH=&#34;</span><span class="si">${</span><span class="n">pkgs</span><span class="o">.</span><span class="n">playwright-driver</span><span class="o">.</span><span class="n">browsers</span><span class="si">}</span><span class="s1">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s1">      </span><span class="si">${</span><span class="n">pre-commit-check</span><span class="o">.</span><span class="n">shellHook</span><span class="si">}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">    &#39;&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">buildInputs</span> <span class="o">=</span> <span class="n">pre-commit-check</span><span class="o">.</span><span class="n">enabledPackages</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">packages</span> <span class="o">=</span> <span class="k">with</span> <span class="n">pkgs</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="c1"># TODO: workout how to use go env</span>
</span></span><span class="line"><span class="cl">      <span class="c1"># goEnv</span>
</span></span><span class="line"><span class="cl">      <span class="n">gomod2nix</span>
</span></span><span class="line"><span class="cl">      <span class="n">go_1_22</span>
</span></span><span class="line"><span class="cl">      <span class="n">playwright-test</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="n">goose</span>
</span></span><span class="line"><span class="cl">      <span class="n">air</span>
</span></span><span class="line"><span class="cl">      <span class="n">golangci-lint</span>
</span></span><span class="line"><span class="cl">      <span class="n">gotools</span>
</span></span><span class="line"><span class="cl">      <span class="n">gotestsum</span>
</span></span><span class="line"><span class="cl">      <span class="n">gocover-cobertura</span>
</span></span><span class="line"><span class="cl">      <span class="n">go-task</span>
</span></span><span class="line"><span class="cl">      <span class="n">go-mockery</span>
</span></span><span class="line"><span class="cl">      <span class="n">goreleaser</span>
</span></span><span class="line"><span class="cl">      <span class="n">golines</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="n">tailwindcss</span>
</span></span><span class="line"><span class="cl">      <span class="n">templ</span>
</span></span><span class="line"><span class="cl">      <span class="n">sqlc</span>
</span></span><span class="line"><span class="cl">    <span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>You can see I have certain tools I want other developers to have access to like <code>go-task</code>, which they will automatically
get when they load into the devshell.</p>
<h2 id="issue">Issue</h2>
<p>This is all great; however, I have noticed that shell completions stopped working. Where I can normally do <code>task &lt;TAB&gt;</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ task tests:e2e
</span></span><span class="line"><span class="cl">build:dev  <span class="o">(</span>Build the app <span class="k">for</span> development, generates all the files needed <span class="k">for</span> the binary.<span class="o">)</span>  generate:sqlc  <span class="o">(</span>Generates the code to interact with SQL DB.<span class="o">)</span>
</span></span><span class="line"><span class="cl">coverage                            <span class="o">(</span>Run the integration tests and gets the code coverage<span class="o">)</span>  lint                                      <span class="o">(</span>Runs the linter.<span class="o">)</span>
</span></span><span class="line"><span class="cl">dev                                       <span class="o">(</span>Start the app in dev mode with live-reloading.<span class="o">)</span>  release                              <span class="o">(</span>Release the CLI tool.<span class="o">)</span>
</span></span><span class="line"><span class="cl">docker:build                                            <span class="o">(</span>Builds a Docker image using Nix.<span class="o">)</span>  tests                                  <span class="o">(</span>Runs all the tests.<span class="o">)</span>
</span></span><span class="line"><span class="cl">docker:load                                <span class="o">(</span>Loads the Docker image from tar <span class="o">(</span>in results<span class="o">)</span>.<span class="o">)</span>  tests:e2e                  <span class="o">(</span>Runs e2e tests with playwright.<span class="o">)</span>
</span></span><span class="line"><span class="cl">docker:publish                                                <span class="o">(</span>Publishes the Docker image<span class="o">)</span>  tests:integration          <span class="o">(</span>Runs all the integration tests.<span class="o">)</span>
</span></span><span class="line"><span class="cl">format                                                               <span class="o">(</span>Runs the formatter.<span class="o">)</span>  tests:unit                        <span class="o">(</span>Runs all the unit tests.<span class="o">)</span>
</span></span></code></pre></div><p>However, in the devshell this does not work until I load into the shell manually <code>nix develop</code>. Which does defeat
the purpose of using <code>nix-direnv</code> as you need to manually run a command now.</p>
<p>I don&rsquo;t know what causes this and will do a deeper dive at some point 🤔.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix Did No Resolve Alias Errors in Podman</title>
      <link>https://haseebmajid.dev/posts/2024-06-15-til-how-to-fix-did-no-resolve-alias-errors-in-podman/</link>
      <pubDate>Sat, 15 Jun 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-06-15-til-how-to-fix-did-no-resolve-alias-errors-in-podman/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix Did No Resolve Alias Errors in Podman&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I was trying to pull docker images using &lt;code&gt;podman&lt;/code&gt;, on an Ubuntu laptop and was getting an error which
looked something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Error: error creating build container: short-name &lt;span class=&#34;s2&#34;&gt;&amp;#34;node:18.17&amp;#34;&lt;/span&gt; did not resolve to an &lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt; and no unqualified-search registries are defined in &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/containers/registries.conf&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is because Podman doesn&amp;rsquo;t allow us to use short names, by default we need to specify the registry i.e. &lt;code&gt;docker.io/node:18.17&lt;/code&gt;.
But for existing &lt;code&gt;docker-compose.yml&lt;/code&gt; files, this would be a pain to edit. Especially because most people use Docker
not Podman. So, in the end, you can edit a config file in home directory to enable the old way of pulling images.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix Did No Resolve Alias Errors in Podman</strong></p>
<p>Recently, I was trying to pull docker images using <code>podman</code>, on an Ubuntu laptop and was getting an error which
looked something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Error: error creating build container: short-name <span class="s2">&#34;node:18.17&#34;</span> did not resolve to an <span class="nb">alias</span> and no unqualified-search registries are defined in <span class="s2">&#34;/etc/containers/registries.conf&#34;</span>
</span></span></code></pre></div><p>This is because Podman doesn&rsquo;t allow us to use short names, by default we need to specify the registry i.e. <code>docker.io/node:18.17</code>.
But for existing <code>docker-compose.yml</code> files, this would be a pain to edit. Especially because most people use Docker
not Podman. So, in the end, you can edit a config file in home directory to enable the old way of pulling images.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nvim ~/.config/containers/registries.conf
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add the following</span>
</span></span><span class="line"><span class="cl">unqualified-search-registries<span class="o">=[</span><span class="s2">&#34;docker.io&#34;</span><span class="o">]</span>
</span></span></code></pre></div><p>You could also do it machine wide by editing the file <code>/etc/containers/registries.conf</code>.</p>
<p>That&rsquo;s it! Real short one today! This just stumped me today for like 20 minutes.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix DNS Resolution Issues in K3s Related to Flannel Networking</title>
      <link>https://haseebmajid.dev/posts/2024-06-02-til-how-to-fix-dns-resolution-issues-in-k3s-related-to-flannel-networking/</link>
      <pubDate>Sun, 02 Jun 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-06-02-til-how-to-fix-dns-resolution-issues-in-k3s-related-to-flannel-networking/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix DNS Resolution Issues in K3s Related to Flannel Networking&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I was trying to set up the kubernetes-dashboard, to make it easier to monitor my k8s cluster. I however noticed
I was getting the following error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;… &amp;gt; add-kubernetes-dashboard via 🐹 v1.22.2 via   via ❄  impure &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;nix-shell-env&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; k$ kubectl logs -n monitoring kubernetes-dashboard-kong-75bb76dd5f-b27ll
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2024/05/05 20:55:21 &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;error&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; 1319#0: *274054 &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;lua&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; init.lua:371: execute&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;: DNS resolution failed: failed to receive reply from UDP server 10.43.0.10:53: timeout. Tried: nil, client: 127.0.0.1, server: kong, request: &lt;span class=&#34;s2&#34;&gt;&amp;#34;GET / HTTP/2.0&amp;#34;&lt;/span&gt;, host: &lt;span class=&#34;s2&#34;&gt;&amp;#34;localhost:8443&amp;#34;&lt;/span&gt;, request_id: &lt;span class=&#34;s2&#34;&gt;&amp;#34;af30b3162db70e2de8f1073a40f7d865&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Weird the DNS resolution seems to be failing, so I decided to follow the
&lt;a href=&#34;https://kubernetes.io/docs/tasks/administer-cluster/dns-debugging-resolution/&#34;&gt;Kubernetes guide&lt;/a&gt; to try to debug issues.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix DNS Resolution Issues in K3s Related to Flannel Networking</strong></p>
<p>Recently, I was trying to set up the kubernetes-dashboard, to make it easier to monitor my k8s cluster. I however noticed
I was getting the following error:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">… &gt; add-kubernetes-dashboard via 🐹 v1.22.2 via   via ❄  impure <span class="o">(</span>nix-shell-env<span class="o">)</span>
</span></span><span class="line"><span class="cl"> k$ kubectl logs -n monitoring kubernetes-dashboard-kong-75bb76dd5f-b27ll
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">2024/05/05 20:55:21 <span class="o">[</span>error<span class="o">]</span> 1319#0: *274054 <span class="o">[</span>lua<span class="o">]</span> init.lua:371: execute<span class="o">()</span>: DNS resolution failed: failed to receive reply from UDP server 10.43.0.10:53: timeout. Tried: nil, client: 127.0.0.1, server: kong, request: <span class="s2">&#34;GET / HTTP/2.0&#34;</span>, host: <span class="s2">&#34;localhost:8443&#34;</span>, request_id: <span class="s2">&#34;af30b3162db70e2de8f1073a40f7d865&#34;</span>
</span></span></code></pre></div><p>Weird the DNS resolution seems to be failing, so I decided to follow the
<a href="https://kubernetes.io/docs/tasks/administer-cluster/dns-debugging-resolution/">Kubernetes guide</a> to try to debug issues.</p>
<p>I found out I couldn&rsquo;t even do a nslookup:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">kubectl <span class="nb">exec</span> -i -t dnsutils -- nslookup kubernetes.default
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">;;</span> connection timed out<span class="p">;</span> no servers could be reached
</span></span><span class="line"><span class="cl"><span class="nb">command</span> terminated with <span class="nb">exit</span> code <span class="m">1</span>
</span></span></code></pre></div><p>I had set up k3s on NixOS (as per the previous posts in this series). In the ended, the issue ending up being not
open the correct ports, we are using the <code>Flannel VXLAN</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. <code>UDP	8472	All nodes	All nodes	Required only for Flannel VXLAN</code>
The <a href="https://github.com/NixOS/nixpkgs/issues/175513#issuecomment-1147755254">GitHub</a> issue that helped me solve my problem.</p>
<p>We need to open up port 8472 in our firewall rules, on my NixOS server we can do something like so.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="n">networking</span><span class="o">.</span><span class="n">firewall</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">allowedUDPPorts</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># ...</span>
</span></span><span class="line"><span class="cl">    <span class="mi">8472</span>
</span></span><span class="line"><span class="cl">  <span class="p">];</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><details
  class="notice danger"
  open="true"
>
    <summary class="notice-title">Security Issues</summary>
  
  The VXLAN port on nodes should not be exposed to the world as it opens up your cluster network to be accessed by anyone. Run your nodes behind a firewall/security group that disables access to port 8472.
</details>

<p>So in my case, since my k8s cluster was multi-node, the nodes couldn&rsquo;t communicate with each other properly.
That&rsquo;s about it, it took me a while to figure out, basically RTFM 😭😭😭.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://docs.k3s.io/installation/requirements#networking">https://docs.k3s.io/installation/requirements#networking</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Pull Submodules in a Nix Derivation</title>
      <link>https://haseebmajid.dev/posts/2024-05-12-til-how-to-pull-submodules-in-a-nix-derivation/</link>
      <pubDate>Sun, 12 May 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-05-12-til-how-to-pull-submodules-in-a-nix-derivation/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Pull Submodules in a Nix Derivation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I was trying to create a derivation which needed to pull git submodules as well. I was getting an error which
look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;data/meson.build:76:0: ERROR: Nonexistent build file &lt;span class=&#34;s1&#34;&gt;&amp;#39;data/submodules/meson.build&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It was coming from this derivation &lt;a href=&#34;https://gitlab.com/hmajid2301/dotfiles/-/blob/c153de146a3bf9339cbef013ac65bc32e6305c8e/packages/gradience/default.nix&#34;&gt;https://gitlab.com/hmajid2301/dotfiles/-/blob/c153de146a3bf9339cbef013ac65bc32e6305c8e/packages/gradience/default.nix&lt;/a&gt; for building the latest version of gradience.&lt;/p&gt;
&lt;p&gt;It turns out when we do a &lt;code&gt;fetchFromGitHub&lt;/code&gt; we need to explicitly tell it to also pull submodules, which makes sense.
So I was able to fix this. I had to add the &lt;code&gt;fetchSubmodules&lt;/code&gt; argument:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Pull Submodules in a Nix Derivation</strong></p>
<p>Recently, I was trying to create a derivation which needed to pull git submodules as well. I was getting an error which
look something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">data/meson.build:76:0: ERROR: Nonexistent build file <span class="s1">&#39;data/submodules/meson.build&#39;</span>
</span></span></code></pre></div><p>It was coming from this derivation <a href="https://gitlab.com/hmajid2301/dotfiles/-/blob/c153de146a3bf9339cbef013ac65bc32e6305c8e/packages/gradience/default.nix">https://gitlab.com/hmajid2301/dotfiles/-/blob/c153de146a3bf9339cbef013ac65bc32e6305c8e/packages/gradience/default.nix</a> for building the latest version of gradience.</p>
<p>It turns out when we do a <code>fetchFromGitHub</code> we need to explicitly tell it to also pull submodules, which makes sense.
So I was able to fix this. I had to add the <code>fetchSubmodules</code> argument:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">pkgs</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">lib</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">fetchFromGitHub</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">  <span class="o">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}:</span>
</span></span><span class="line"><span class="cl"><span class="n">pkgs</span><span class="o">.</span><span class="n">python3Packages</span><span class="o">.</span><span class="n">buildPythonApplication</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">pname</span> <span class="o">=</span> <span class="s2">&#34;gradience&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">version</span> <span class="o">=</span> <span class="s2">&#34;0.8.0-beta1&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">src</span> <span class="o">=</span> <span class="n">fetchFromGitHub</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">owner</span> <span class="o">=</span> <span class="s2">&#34;GradienceTeam&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">repo</span> <span class="o">=</span> <span class="s2">&#34;Gradience&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rev</span> <span class="o">=</span> <span class="s2">&#34;90b774174da0e3c6b5314e38226bea653a5bf57a&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">sha256</span> <span class="o">=</span> <span class="s2">&#34;sha256-C0GV6vOEZ0wTaKO7BgGuFvHsHeaVwH0W1U8yKUMrO9c=&#34;</span><span class="p">;</span>
</span></span><span class="line hl"><span class="cl">    <span class="n">fetchSubmodules</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>That&rsquo;s it! A simple fix, but took me longer than it should&rsquo;ve done to figure it out.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix Neorg Metadata Treesitter Issues With Nixvim</title>
      <link>https://haseebmajid.dev/posts/2024-04-21-til-how-to-fix-neorg-metadata-treesitter-issues-with-nixvim/</link>
      <pubDate>Sun, 21 Apr 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-04-21-til-how-to-fix-neorg-metadata-treesitter-issues-with-nixvim/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix Neorg Metadata Tree Sitter Issues With NixVim&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you are like me, you may be configuring your Neovim configuration using NixVim. Which is a &amp;ldquo;framework&amp;rdquo; making it
easier to configure Neovim using mostly Nix configuration. Allowing us to keep most of our config in one language,
at least in my case.&lt;/p&gt;
&lt;p&gt;I started using Neorg to manage my notes and to-do lists in my &amp;ldquo;second-brain&amp;rdquo;, but noticed that the metadata part
was not being highlighted as I expected.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix Neorg Metadata Tree Sitter Issues With NixVim</strong></p>
<p>If you are like me, you may be configuring your Neovim configuration using NixVim. Which is a &ldquo;framework&rdquo; making it
easier to configure Neovim using mostly Nix configuration. Allowing us to keep most of our config in one language,
at least in my case.</p>
<p>I started using Neorg to manage my notes and to-do lists in my &ldquo;second-brain&rdquo;, but noticed that the metadata part
was not being highlighted as I expected.</p>
<p>My config looked something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">programs</span><span class="o">.</span><span class="n">nixvim</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">plugins</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">neorg</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">lazyLoading</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">modules</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="c1"># ...</span>
</span></span><span class="line"><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="n">treesitter</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">grammarPackages</span> <span class="o">=</span> <span class="k">with</span> <span class="n">config</span><span class="o">.</span><span class="n">programs</span><span class="o">.</span><span class="n">nixvim</span><span class="o">.</span><span class="n">plugins</span><span class="o">.</span><span class="n">treesitter</span><span class="o">.</span><span class="n">package</span><span class="o">.</span><span class="n">builtGrammars</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="n">norg</span>
</span></span><span class="line"><span class="cl">        <span class="p">];</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Turns out there is another tree sitter package for the n
Neorg metadata, but this is not available with nvim-treesitter.
Hence, also not available with Nixvim. I was able to resolve my issue my using the tree-sitter specific grammar like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">programs</span><span class="o">.</span><span class="n">nixvim</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">plugins</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">neorg</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">lazyLoading</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">modules</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="c1"># ...</span>
</span></span><span class="line"><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="n">treesitter</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line hl"><span class="cl">        <span class="n">grammarPackages</span> <span class="o">=</span> <span class="k">with</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">tree-sitter-grammars</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line hl"><span class="cl">          <span class="n">tree-sitter-norg</span>
</span></span><span class="line hl"><span class="cl">          <span class="n">tree-sitter-norg-meta</span>
</span></span><span class="line hl"><span class="cl">        <span class="p">];</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>It looks like this. That&rsquo;s it!</p>
<p><img
        loading="lazy"
        src="/posts/2024-04-21-til-how-to-fix-neorg-metadata-treesitter-issues-with-nixvim/images/neorg-metadata.png"
        type=""
        alt="Neorg Metadata"
        
      /></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Set up Layouts in Zellij That Use Direnv and Nix</title>
      <link>https://haseebmajid.dev/posts/2024-03-18-til-how-to-setup-layouts-in-zellij-that-use-direnv-and-nix/</link>
      <pubDate>Mon, 18 Mar 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-03-18-til-how-to-setup-layouts-in-zellij-that-use-direnv-and-nix/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Set up Layouts in Zellij That Use Direnv and Nix&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have been using &lt;a href=&#34;https://github.com/zellij-org/zellij&#34;&gt;Zellij&lt;/a&gt; for a while now. I tried to set up layouts for
one of my personal projects. So that we could have tests and linting running and any other tasks we may want
whilst doing development &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;However, I had an issue working out how to call commands that required direnv and nix to set up development environments.
In my case, my nix dev shell installed the go-task tool to run tasks such as &lt;code&gt;task lint&lt;/code&gt; or &lt;code&gt;task tests&lt;/code&gt;. However
the shell that zellij was running the commands in for the layout did not load my Nix dev shell, so the go-task binary
was not available.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Set up Layouts in Zellij That Use Direnv and Nix</strong></p>
<p>I have been using <a href="https://github.com/zellij-org/zellij">Zellij</a> for a while now. I tried to set up layouts for
one of my personal projects. So that we could have tests and linting running and any other tasks we may want
whilst doing development <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<p>However, I had an issue working out how to call commands that required direnv and nix to set up development environments.
In my case, my nix dev shell installed the go-task tool to run tasks such as <code>task lint</code> or <code>task tests</code>. However
the shell that zellij was running the commands in for the layout did not load my Nix dev shell, so the go-task binary
was not available.</p>
<p>So to fix this, we need to do something like this <code>layout.kdl</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kdl" data-lang="kdl"><span class="line"><span class="cl"><span class="nl">layout</span><span class="w"> </span><span class="o">{</span><span class="nl">
</span></span></span><span class="line"><span class="cl"><span class="nl">    pane</span><span class="w"> </span><span class="na">size=</span><span class="m">1</span><span class="w"> </span><span class="na">borderless=</span><span class="s">true</span><span class="w"> </span><span class="o">{</span><span class="nl">
</span></span></span><span class="line"><span class="cl"><span class="nl">        plugin</span><span class="w"> </span><span class="na">location=</span><span class="s">&#34;zellij:tab-bar&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nl">    pane</span><span class="w"> </span><span class="o">{</span><span class="nl">
</span></span></span><span class="line"><span class="cl"><span class="nl">        command</span><span class="w"> </span><span class="s">&#34;fish&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nl">        args</span><span class="w"> </span><span class="s">&#34;-c&#34;</span><span class="w"> </span><span class="s">&#34;direnv exec . task lint&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nl">    pane</span><span class="w"> </span><span class="o">{</span><span class="nl">
</span></span></span><span class="line"><span class="cl"><span class="nl">        command</span><span class="w"> </span><span class="s">&#34;fish&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nl">        args</span><span class="w"> </span><span class="s">&#34;-c&#34;</span><span class="w"> </span><span class="s">&#34;direnv exec . task tests&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nl">    pane</span><span class="w"> </span><span class="o">{</span><span class="nl">
</span></span></span><span class="line"><span class="cl"><span class="nl">        command</span><span class="w"> </span><span class="s">&#34;docker-compose&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nl">        args</span><span class="w"> </span><span class="s">&#34;up&#34;</span><span class="w"> </span><span class="s">&#34;--build -d&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="o">}</span><span class="w">
</span></span></span></code></pre></div><p>Where the key being we need to execute the direnv environment i.e. <code>direnv exec .</code>, then we can run commands like
normal. Where direnv <code>.envrc</code> file contains <code>use flake</code>. That&rsquo;s it! If you want Zellij to use direnv and load your
nix flake dev shell, you have to add a bit of boilerplate, which is not ideal but</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://github.com/zellij-org/zellij/issues/2294">https://github.com/zellij-org/zellij/issues/2294</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Get Sway Notification Center to Play Nice With Waybar</title>
      <link>https://haseebmajid.dev/posts/2024-03-15-til-how-to-get-swaync-to-play-nice-with-waybar/</link>
      <pubDate>Fri, 15 Mar 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-03-15-til-how-to-get-swaync-to-play-nice-with-waybar/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Get swaync to Play Nice With Waybar&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I added Sway Notification Center as my notification manager and added a small &amp;ldquo;widget&amp;rdquo; to my Waybar, so I can see how many notifications
I have and silence notifications by clicking on it. However, I found when I opened the swaync sidebar, in my case by
right-clicking on the icon. I found that I could not click on anything else on my Waybar like workspaces. Now I know
I should be using my keyboard, but sometimes it&amp;rsquo;s just easier to use a mouse.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Get swaync to Play Nice With Waybar</strong></p>
<p>I added Sway Notification Center as my notification manager and added a small &ldquo;widget&rdquo; to my Waybar, so I can see how many notifications
I have and silence notifications by clicking on it. However, I found when I opened the swaync sidebar, in my case by
right-clicking on the icon. I found that I could not click on anything else on my Waybar like workspaces. Now I know
I should be using my keyboard, but sometimes it&rsquo;s just easier to use a mouse.</p>
<p>The fix I found was on <a href="https://old.reddit.com/r/swaywm/comments/133cffq/swaync_weird_behavior_on_waybar/">Reddit</a>.
I use nix and configure Waybar using home-manager, the on-click actions now have a small sleep, which I don&rsquo;t even
notice, and this resolves the above issue.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;custom/notification&#34;</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">tooltip</span> <span class="o">=</span> <span class="no">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">format</span> <span class="o">=</span> <span class="s2">&#34;{} {icon}&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;format-icons&#34;</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">notification</span> <span class="o">=</span> <span class="s2">&#34;󱅫&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">none</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;dnd-notification&#34;</span> <span class="o">=</span> <span class="s2">&#34; &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;dnd-none&#34;</span> <span class="o">=</span> <span class="s2">&#34;󰂛&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;inhibited-notification&#34;</span> <span class="o">=</span> <span class="s2">&#34; &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;inhibited-none&#34;</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;dnd-inhibited-notification&#34;</span> <span class="o">=</span> <span class="s2">&#34; &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;dnd-inhibited-none&#34;</span> <span class="o">=</span> <span class="s2">&#34; &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;return-type&#34;</span> <span class="o">=</span> <span class="s2">&#34;json&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;exec-if&#34;</span> <span class="o">=</span> <span class="s2">&#34;which swaync-client&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">exec</span> <span class="o">=</span> <span class="s2">&#34;swaync-client -swb&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;on-click&#34;</span> <span class="o">=</span> <span class="s2">&#34;sleep 0.1 &amp;&amp; swaync-client -t -sw&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;on-click-right&#34;</span> <span class="o">=</span> <span class="s2">&#34;sleep 0.1 &amp;&amp; swaync-client -d -sw&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">escape</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>That&rsquo;s it!</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: Clean Up Tmux Service When Removed by Home Manager</title>
      <link>https://haseebmajid.dev/posts/2024-03-10-til-clean-up-tmux-service-when-removed-by-home-manager/</link>
      <pubDate>Sun, 10 Mar 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-03-10-til-clean-up-tmux-service-when-removed-by-home-manager/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: Clean Up Tmux Service When Removed by Home Manager&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I stopped using tmux to try zellij, however I noticed when I removed tmux from my nix config. I was getting
the following error, when rebuilding my home-manager config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;The user systemd session is degraded:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  UNIT         LOAD   ACTIVE SUB    DESCRIPTION
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;● tmux.service loaded failed failed tmux default session &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;detached&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Legend: LOAD   → Reflects whether the unit definition was properly loaded.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        ACTIVE → The high-level unit activation state, i.e. generalization of SUB.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        SUB    → The low-level unit activation state, values depend on unit type.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I was wondering where this error was coming from, turns it the symlink to tmux.service has not been deleted that
nix would create.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: Clean Up Tmux Service When Removed by Home Manager</strong></p>
<p>Recently I stopped using tmux to try zellij, however I noticed when I removed tmux from my nix config. I was getting
the following error, when rebuilding my home-manager config:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">The user systemd session is degraded:
</span></span><span class="line"><span class="cl">  UNIT         LOAD   ACTIVE SUB    DESCRIPTION
</span></span><span class="line"><span class="cl">● tmux.service loaded failed failed tmux default session <span class="o">(</span>detached<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Legend: LOAD   → Reflects whether the unit definition was properly loaded.
</span></span><span class="line"><span class="cl">        ACTIVE → The high-level unit activation state, i.e. generalization of SUB.
</span></span><span class="line"><span class="cl">        SUB    → The low-level unit activation state, values depend on unit type.
</span></span></code></pre></div><p>I was wondering where this error was coming from, turns it the symlink to tmux.service has not been deleted that
nix would create.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ls -al ~/.config/systemd/user/tmux.service
</span></span><span class="line"><span class="cl">Permissions Size User        Group       Date Modified Name
</span></span><span class="line"><span class="cl">.rw-rw-r--   <span class="m">453</span> haseebmajid haseebmajid <span class="m">22</span> Aug  <span class="m">2023</span>   /home/haseebmajid/.config/systemd/user/tmux.service
</span></span></code></pre></div><p>If we look at other systemd services we can see them symlinked to a nix package in the nix store.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ls -al ~/.config/systemd/user
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - haseebmajid haseebmajid <span class="m">20</span> Feb 17:04   spotifyd.service -&gt; /nix/store/7v52bpcyi0zqv012rrmd7s2r742hb2cy-home-manager-files/.config/systemd/user/spotifyd.service
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - haseebmajid haseebmajid <span class="m">20</span> Feb 17:04   swayidle.service -&gt; /nix/store/7v52bpcyi0zqv012rrmd7s2r742hb2cy-home-manager-files/.config/systemd/user/swayidle.service
</span></span></code></pre></div><p>So we can simply remove the tmux file, <code>rm ~/.config/systemd/user/tmux.service</code>. I should look into why this symlink
is not removed.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Add New Vim Plugins to nixpkgs Repository</title>
      <link>https://haseebmajid.dev/posts/2024-02-20-til-how-to-add-new-vim-plugins-to-nixpkgs-repository/</link>
      <pubDate>Tue, 20 Feb 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-02-20-til-how-to-add-new-vim-plugins-to-nixpkgs-repository/</guid>
      <description>&lt;p&gt;Recently, I wanted to add a Neovim plugin to nixpkgs, so I can then add it to NixVim. I tried following the guide
from the &lt;a href=&#34;https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/vim.section.md#adding-new-plugins-to-nixpkgs-adding-new-plugins-to-nixpkgs&#34;&gt;docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, I kept getting the following errors:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nix-shell -p vimPluginsUpdater --run vim-plugins-updater
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;error:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       … &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; calling the &lt;span class=&#34;s1&#34;&gt;&amp;#39;derivationStrict&amp;#39;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;builtin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         at /builtin/derivation.nix:9:12: &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; not available&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       … &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; evaluating derivation &lt;span class=&#34;s1&#34;&gt;&amp;#39;shell&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         whose name attribute is located at /nix/store/whhzjfgalghpm34irclh01c0afynmyll-nixpkgs/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:300:7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       … &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; evaluating attribute &lt;span class=&#34;s1&#34;&gt;&amp;#39;buildInputs&amp;#39;&lt;/span&gt; of derivation &lt;span class=&#34;s1&#34;&gt;&amp;#39;shell&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         at /nix/store/whhzjfgalghpm34irclh01c0afynmyll-nixpkgs/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:347:7:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          346&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;       &lt;span class=&#34;nv&#34;&gt;depsHostHost&lt;/span&gt;                &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; lib.elemAt &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;lib.elemAt dependencies 1&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; 0&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          347&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;       &lt;span class=&#34;nv&#34;&gt;buildInputs&lt;/span&gt;                 &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; lib.elemAt &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;lib.elemAt dependencies 1&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; 1&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;             &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;       ^
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          348&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;       &lt;span class=&#34;nv&#34;&gt;depsTargetTarget&lt;/span&gt;            &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; lib.elemAt &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;lib.elemAt dependencies 2&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; 0&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       error: undefined variable &lt;span class=&#34;s1&#34;&gt;&amp;#39;vimPluginsUpdater&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       at «string»:1:107:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            1&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;...&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;@args: with import &amp;lt;nixpkgs&amp;gt; args&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;pkgs.runCommandCC or pkgs.runCommand&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;shell&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;buildInputs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;vimPluginsUpdater&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or I was getting 429 network errors, too many requests to GitHub.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Recently, I wanted to add a Neovim plugin to nixpkgs, so I can then add it to NixVim. I tried following the guide
from the <a href="https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/vim.section.md#adding-new-plugins-to-nixpkgs-adding-new-plugins-to-nixpkgs">docs</a>.</p>
<p>However, I kept getting the following errors:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nix-shell -p vimPluginsUpdater --run vim-plugins-updater
</span></span><span class="line"><span class="cl">error:
</span></span><span class="line"><span class="cl">       … <span class="k">while</span> calling the <span class="s1">&#39;derivationStrict&#39;</span> <span class="nb">builtin</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">         at /builtin/derivation.nix:9:12: <span class="o">(</span><span class="nb">source</span> not available<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">       … <span class="k">while</span> evaluating derivation <span class="s1">&#39;shell&#39;</span>
</span></span><span class="line"><span class="cl">         whose name attribute is located at /nix/store/whhzjfgalghpm34irclh01c0afynmyll-nixpkgs/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:300:7
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">       … <span class="k">while</span> evaluating attribute <span class="s1">&#39;buildInputs&#39;</span> of derivation <span class="s1">&#39;shell&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">         at /nix/store/whhzjfgalghpm34irclh01c0afynmyll-nixpkgs/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:347:7:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">          346<span class="p">|</span>       <span class="nv">depsHostHost</span>                <span class="o">=</span> lib.elemAt <span class="o">(</span>lib.elemAt dependencies 1<span class="o">)</span> 0<span class="p">;</span>
</span></span><span class="line"><span class="cl">          347<span class="p">|</span>       <span class="nv">buildInputs</span>                 <span class="o">=</span> lib.elemAt <span class="o">(</span>lib.elemAt dependencies 1<span class="o">)</span> 1<span class="p">;</span>
</span></span><span class="line"><span class="cl">             <span class="p">|</span>       ^
</span></span><span class="line"><span class="cl">          348<span class="p">|</span>       <span class="nv">depsTargetTarget</span>            <span class="o">=</span> lib.elemAt <span class="o">(</span>lib.elemAt dependencies 2<span class="o">)</span> 0<span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">       error: undefined variable <span class="s1">&#39;vimPluginsUpdater&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">       at «string»:1:107:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            1<span class="p">|</span> <span class="o">{</span>...<span class="o">}</span>@args: with import &lt;nixpkgs&gt; args<span class="p">;</span> <span class="o">(</span>pkgs.runCommandCC or pkgs.runCommand<span class="o">)</span> <span class="s2">&#34;shell&#34;</span> <span class="o">{</span> <span class="nv">buildInputs</span> <span class="o">=</span> <span class="o">[</span> <span class="o">(</span>vimPluginsUpdater<span class="o">)</span> <span class="o">]</span><span class="p">;</span> <span class="o">}</span> <span class="s2">&#34;&#34;</span>
</span></span></code></pre></div><p>Or I was getting 429 network errors, too many requests to GitHub.</p>
<h2 id="solution">Solution</h2>
<p>I found this great person who was able to solve my issue on <a href="https://discourse.nixos.org/t/adding-new-neovim-to-nixpkgs/34834/2">discourse</a>.
Assuming you have a fork of nixpkgs and have to clone it locally, i.e. <code>git clone https://github.com/hmajid2301/nixpkgs.git</code></p>
<ol>
<li>Update <code>nixpkgs/pkgs/applications/editors/vim/plugins/vim-plugin-names</code></li>
<li>Can do this using the <code>./update.py add &quot;gbprod/yanky.nvim&quot;</code> (where <code>gbprod/yanky.nvim</code> is the path to git repository)</li>
<li>Export your GitHub Personal Token</li>
<li>You can create one by following <a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic">this link</a></li>
<li><code>export GITHUB_API_TOKEN=your_token</code></li>
<li>I will do a post in the future about how you can do this in fish shell and keep secrets out of your shell history.</li>
<li><code>nix-shell -I nixpkgs=channel:nixpkgs-unstable -p vimPluginsUpdater --run vim-plugins-updater</code></li>
<li>Make sure to run this in the repository root</li>
<li>Push your changes and create a PR with nixpkgs repo</li>
<li>You will likely need to rebase your commits to follow the contribution guidelines, check those when creating the PR</li>
</ol>
<p>That&rsquo;s it! I am not sure if this will be useful for others (I will most likely reference this myself in the future), but
that&rsquo;s the easiest way I found to add new vim plugins to nixpkgs.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix Firefox Rendering Bug in Hyprland</title>
      <link>https://haseebmajid.dev/posts/2024-02-15-til-how-to-fix-firefox-rendering-bug-in-hyprland/</link>
      <pubDate>Thu, 15 Feb 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-02-15-til-how-to-fix-firefox-rendering-bug-in-hyprland/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix Firefox Rendering Bug in Hyprland&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I had an issue with my Ubuntu laptop running Hyprland, when running Firefox it had this ugly border around
it. Which looked something like this:&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2024-02-15-til-how-to-fix-firefox-rendering-bug-in-hyprland/images/firefox.png&#34;
        type=&#34;&#34;
        alt=&#34;Firefox&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;You can see a weird border around the browser, and if you try to view some of the context menus, they appear small and difficult to read.&lt;/p&gt;
&lt;h2 id=&#34;fix&#34;&gt;Fix&lt;/h2&gt;
&lt;p&gt;As per this &lt;a href=&#34;https://old.reddit.com/r/hyprland/comments/18o8m8q/firefox_croppingbad_rendering/&#34;&gt;Reddit thread&lt;/a&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.
There are two fixes, one upgrade to version 0.33 which I could not easily do with Ubuntu. So I used the other fix,&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix Firefox Rendering Bug in Hyprland</strong></p>
<p>Recently, I had an issue with my Ubuntu laptop running Hyprland, when running Firefox it had this ugly border around
it. Which looked something like this:</p>
<p><img
        loading="lazy"
        src="/posts/2024-02-15-til-how-to-fix-firefox-rendering-bug-in-hyprland/images/firefox.png"
        type=""
        alt="Firefox"
        
      /></p>
<p>You can see a weird border around the browser, and if you try to view some of the context menus, they appear small and difficult to read.</p>
<h2 id="fix">Fix</h2>
<p>As per this <a href="https://old.reddit.com/r/hyprland/comments/18o8m8q/firefox_croppingbad_rendering/">Reddit thread</a> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.
There are two fixes, one upgrade to version 0.33 which I could not easily do with Ubuntu. So I used the other fix,</p>
<ul>
<li>Right click on title bar</li>
<li>Select <code>Customize Toolbar..</code></li>
<li>Then check <code>Title Bar</code>
<ul>
<li>You may have to full-screen the app to make it easier to select the title bar</li>
</ul>
</li>
</ul>
<p><img
        loading="lazy"
        src="/posts/2024-02-15-til-how-to-fix-firefox-rendering-bug-in-hyprland/images/title.png"
        type=""
        alt="Title Bar"
        
      /></p>
<h3 id="hyprland-version">Hyprland Version</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hyprctl version
</span></span><span class="line"><span class="cl">Hyprland, built from branch HEAD at commit 5b8cfdf2efc44106b61e60c642fd964823fd89f3  <span class="o">(</span>props: bump ver to v0.31.0<span class="o">)</span>.
</span></span><span class="line"><span class="cl">Tag: v0.31.0
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">flags: <span class="o">(</span><span class="k">if</span> any<span class="o">)</span>
</span></span><span class="line"><span class="cl">debug
</span></span></code></pre></div><div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Reddit Post with Fix: <a href="https://old.reddit.com/r/hyprland/comments/18o8m8q/firefox_croppingbad_rendering/">https://old.reddit.com/r/hyprland/comments/18o8m8q/firefox_croppingbad_rendering/</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>How to Move Files Between Two Git Repositories and Keep its History</title>
      <link>https://haseebmajid.dev/posts/2024-02-11-til-how-to-move-a-file-between-repos-and-keep-its-git-history/</link>
      <pubDate>Sun, 11 Feb 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-02-11-til-how-to-move-a-file-between-repos-and-keep-its-git-history/</guid>
      <description>&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;Recently, I had to move one of my to-do files from its own repository, &lt;code&gt;todo&lt;/code&gt;, to my &lt;code&gt;second-brain&lt;/code&gt; repository.
So I could better keep track of my ideas, and tasks to be done. However, I realised just copying the file over I
would lose all the git history the file had.&lt;/p&gt;
&lt;p&gt;Strictly speaking, I don&amp;rsquo;t need the git history of that file, as the most important thing is the current tasks to be
completed. I could, also, go look in the older repository if I really needed to see the file history. However, I decided it would be a nice exercise to learn how to copy files over and keep their history.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="background">Background</h2>
<p>Recently, I had to move one of my to-do files from its own repository, <code>todo</code>, to my <code>second-brain</code> repository.
So I could better keep track of my ideas, and tasks to be done. However, I realised just copying the file over I
would lose all the git history the file had.</p>
<p>Strictly speaking, I don&rsquo;t need the git history of that file, as the most important thing is the current tasks to be
completed. I could, also, go look in the older repository if I really needed to see the file history. However, I decided it would be a nice exercise to learn how to copy files over and keep their history.</p>
<h2 id="how">How?</h2>
<p>So how can we do just that? In this example, we will copy a file from <code>todo</code> to
<code>second-brain</code>.</p>
<p>So clone both repos i.e.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone git@git.com/todo.git
</span></span><span class="line"><span class="cl">git clone git@git.com/second-brain.git
</span></span></code></pre></div><p>Then we will use the <a href="https://github.com/newren/git-filter-repo">git-filter-repo</a> tool which we can use to rewrite our
git history.</p>
<blockquote>
<p>extract the history of a single directory, src/. This means that only paths under src/ remain in the repo, and any commits that only touched paths outside this directory will be removed. - git filter repo README</p>
</blockquote>
<p>If you are using the Nix package manager, you can do something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nix-shell -p git-filter-repo
</span></span></code></pre></div><p>Then let&rsquo;s create a new branch on our source repo (<code>todo</code>), then find all commits that are related to the <code>todo.norg</code> file.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> todo
</span></span><span class="line"><span class="cl">git checkout -b filter
</span></span><span class="line"><span class="cl">git filter-repo --path todo.norg --refs refs/heads/filter --force
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">git filter-repo --path todo.norg --refs refs/heads/filter --force
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Parsed 69 commits</span>
</span></span><span class="line"><span class="cl"><span class="c1"># New history written in 0.02 seconds...</span>
</span></span><span class="line"><span class="cl"><span class="c1"># HEAD is now at 21e6ae4 chore: Update ToDos</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Completely finished after 0.03 seconds.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">git log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># commit 21e6ae42c550b2fdd76a1a7c34f8574eb529175d</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Author: Haseeb Majid &lt;hello@haseebmajid.dev&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Date:   Sun Feb 4 22:46:36 2024 +0000</span>
</span></span><span class="line"><span class="cl"><span class="c1"># </span>
</span></span><span class="line"><span class="cl"><span class="c1">#     chore: Update ToDos</span>
</span></span><span class="line"><span class="cl"><span class="c1"># </span>
</span></span><span class="line"><span class="cl"><span class="c1"># commit c0e125be9bddf6666fc321ad3ea1b51e437e4bfc</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Author: Haseeb Majid &lt;hello@haseebmajid.dev&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Date:   Fri Feb 2 22:53:15 2024 +0000</span>
</span></span><span class="line"><span class="cl"><span class="c1"># </span>
</span></span><span class="line"><span class="cl"><span class="c1">#     chore: Update ToDos</span>
</span></span></code></pre></div><p>Then go to our target repo <code>second-brain</code>, we will add the <code>todo</code> repo as a local source to git. Then merge in the changes
on the <code>filter</code> branch. We also need to pass the &ndash;allow-unrelated-histories flag tells Git to allow the merge,
even if the histories of the branches don&rsquo;t share a common commit.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> second-brain
</span></span><span class="line"><span class="cl">git checkout -b filter
</span></span><span class="line"><span class="cl">git remote add todo-source ../todo
</span></span><span class="line"><span class="cl">git fetch todo-source
</span></span><span class="line"><span class="cl">git branch todo-source remotes/todo-source/filter
</span></span><span class="line"><span class="cl">git merge todo-source --allow-unrelated-histories
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Merge changes into main branch</span>
</span></span><span class="line"><span class="cl">git checkout main
</span></span><span class="line"><span class="cl">git merge filter
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Delete reference to remote and branch</span>
</span></span><span class="line"><span class="cl">git remote rm todo-source
</span></span><span class="line"><span class="cl">git branch -d filter
</span></span></code></pre></div><p>Now we will have the <code>todo.norg</code> in our <code>second-brain</code> repo with the git history of the file. If we now look at the
git log, we would see all those commits updating the to-do file.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li>Useful Links:
<ul>
<li><a href="https://www.johno.com/move-directory-between-repos-with-git-history">https://www.johno.com/move-directory-between-repos-with-git-history</a></li>
<li><a href="https://blog.billyc.io/how-to-copy-one-or-more-files-from-one-git-repo-to-another-and-keep-the-git-history/">https://blog.billyc.io/how-to-copy-one-or-more-files-from-one-git-repo-to-another-and-keep-the-git-history/</a></li>
</ul>
</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to fix being unable to change locations in Mullvad VPN on NixOS</title>
      <link>https://haseebmajid.dev/posts/2024-01-14-til-how-to-fix-unable-to-change-locations-in-mullvad-on-nixos/</link>
      <pubDate>Sun, 14 Jan 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-01-14-til-how-to-fix-unable-to-change-locations-in-mullvad-on-nixos/</guid>
      <description>&lt;p&gt;Recently, I was unable to change the location on my Mullvad VPN from other thing other than sweden. Even using the
mullvad cli tool I would keep getting errors like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;invalid argument for type conversion: missing custom lists settings
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;it turned out to somehow a mismatch in versions where everything was running 2023.6 but my mullvad cli was using
2023.5. So I ended up fixing this by changing my config to:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Recently, I was unable to change the location on my Mullvad VPN from other thing other than sweden. Even using the
mullvad cli tool I would keep getting errors like:</p>
<pre tabindex="0"><code>invalid argument for type conversion: missing custom lists settings
</code></pre><p>it turned out to somehow a mismatch in versions where everything was running 2023.6 but my mullvad cli was using
2023.5. So I ended up fixing this by changing my config to:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">services</span><span class="o">.</span><span class="n">mullvad-vpn</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">package</span> <span class="o">=</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">mullvad-vpn</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Where setting the package to <code>mullvad-vpn</code>, which then installed the correct version of the mullvad cli tool and I was
then able to change locations using the gui as per usual. No idea why there was a version mismatch.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix `Verification Failed` With Ventoy USB</title>
      <link>https://haseebmajid.dev/posts/2024-01-09-til-how-to-fix-verification-failed-with-ventoy-usb/</link>
      <pubDate>Tue, 09 Jan 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-01-09-til-how-to-fix-verification-failed-with-ventoy-usb/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix &lt;code&gt;Verification Failed&lt;/code&gt; With Ventoy USB&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I tried to boot with my Ventoy USB on my new AMD motherboard Framework. However, I was getting a which looked
like &lt;code&gt;Verification failed:(0x1A) Security Violation&lt;/code&gt;. It turns out this was because secure boot was turned on. So we
needed to turn it off initially to boot off the Ventoy. You can follow the instructions
&lt;a href=&#34;https://community.frame.work/t/solved-secure-boot-and-custom-keys-on-the-amd-motherboard/38362/3&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We can then turn on secure boot after, I will do a future post how we can do this with NixOS. When I get it working.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix <code>Verification Failed</code> With Ventoy USB</strong></p>
<p>Recently, I tried to boot with my Ventoy USB on my new AMD motherboard Framework. However, I was getting a which looked
like <code>Verification failed:(0x1A) Security Violation</code>. It turns out this was because secure boot was turned on. So we
needed to turn it off initially to boot off the Ventoy. You can follow the instructions
<a href="https://community.frame.work/t/solved-secure-boot-and-custom-keys-on-the-amd-motherboard/38362/3">here</a>.</p>
<p>We can then turn on secure boot after, I will do a future post how we can do this with NixOS. When I get it working.</p>
<p>That&rsquo;s it! Super short post this time.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://askubuntu.com/questions/1456460/verification-failed-0x1a-security-violation-while-installing-ubuntu">SO Post</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: Show to Use the Media Keys on a ZSA Keyboard With Hyprland</title>
      <link>https://haseebmajid.dev/posts/2024-01-01-how-to-use-the-media-keys-on-a-zsa-keyboard-with-hyprland/</link>
      <pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2024-01-01-how-to-use-the-media-keys-on-a-zsa-keyboard-with-hyprland/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: Show to Use the Media Keys on a ZSA Keyboard With Hyprland&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I started using a ZSA Voyager split keyboard, moving to this keyboard has some advantages but the last thing
I felt I was missing from my old keyboard (which has a volume knob) was being able to control the volume. So I set up
the key maps in their software (Oryx) however, I noticed that binding were not working.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: Show to Use the Media Keys on a ZSA Keyboard With Hyprland</strong></p>
<p>Recently, I started using a ZSA Voyager split keyboard, moving to this keyboard has some advantages but the last thing
I felt I was missing from my old keyboard (which has a volume knob) was being able to control the volume. So I set up
the key maps in their software (Oryx) however, I noticed that binding were not working.</p>
<p>Where I had something like this:</p>
<pre tabindex="0"><code>bind=,XF86AudioRaiseVolume,exec, volume --inc
bind=,XF86AudioLowerVolume,exec, volume --dec
bind=,XF86AudioMute,exec, volume --toggle
bind=,XF86AudioMicMute,exec, volume --toggle-mic
</code></pre><p>This worked with my old keyboard just fine, however with my new keyboard, I realised I was pressing a key to change
the layers to access the media keys. I press what would normally be a Shift key to change to layer 3, where my media
keys are. As I don&rsquo;t have enough keys to do that all in one layer, like I could do on my other keyboard.</p>
<p></p>
<p>I think since I was holding down a key at the same time as pressing the media keys, I ended up using <code>bindi</code>
to fix my issue.</p>
<blockquote>
<p>i -&gt; ignore mods, will ignore modifiers - <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
</blockquote>
<p>So now my config looks like:</p>
<pre tabindex="0"><code>bindi=,XF86AudioRaiseVolume,exec, volume --inc
bindi=,XF86AudioLowerVolume,exec, volume --dec
bindi=,XF86AudioMute,exec, volume --toggle
bindi=,XF86AudioMicMute,exec, volume --toggle-mic
</code></pre><p>That&rsquo;s it!</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://wiki.hyprland.org/hyprland-wiki/pages/Configuring/Binds/#bind-flags">https://wiki.hyprland.org/hyprland-wiki/pages/Configuring/Binds/#bind-flags</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Use Default Values in docker-compose.yml</title>
      <link>https://haseebmajid.dev/posts/2023-12-30-til-how-to-use-default-values-in-docker-compose-yml/</link>
      <pubDate>Sat, 30 Dec 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-12-30-til-how-to-use-default-values-in-docker-compose-yml/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Use Default Values in docker-compose.yml&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sometimes we want to use env variables in our docker-compose files like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;m&#34;&gt;8000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here we are going to use the GitLab CI dependency proxy to pull our Nginx image, so we can speed up our pipelines but
also avoid being rate limited by docker hub. However, when running this locally, we will need to make sure the
&lt;code&gt;CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX&lt;/code&gt; env variable is set. Which just adds a bit more work, instead we can leverage
some of the special syntax docker-compose provides &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, which I think it inherits from bash.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Use Default Values in docker-compose.yml</strong></p>
<p>Sometimes we want to use env variables in our docker-compose files like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">client</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="m">8000</span><span class="p">:</span><span class="m">80</span><span class="w">
</span></span></span></code></pre></div><p>Here we are going to use the GitLab CI dependency proxy to pull our Nginx image, so we can speed up our pipelines but
also avoid being rate limited by docker hub. However, when running this locally, we will need to make sure the
<code>CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX</code> env variable is set. Which just adds a bit more work, instead we can leverage
some of the special syntax docker-compose provides <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, which I think it inherits from bash.</p>
<p>Where we can use interpolation to set default values if the env variable is not set:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">client</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX:-docker.io}/nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="m">8000</span><span class="p">:</span><span class="m">80</span><span class="w">
</span></span></span></code></pre></div><p>In this case, <code>:-</code> will use docker.io if the env variable is not set or is empty. There are several other variations
you can find in the footnote below.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://docs.docker.com/compose/environment-variables/env-file/">https://docs.docker.com/compose/environment-variables/env-file/</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Use Open Buffers When Debugging With Neovim&#39;s DAP Plugin</title>
      <link>https://haseebmajid.dev/posts/2023-12-24-til-how-to-use-open-buffers-when-debugging-with-neovim-dap-plugin/</link>
      <pubDate>Sun, 24 Dec 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-12-24-til-how-to-use-open-buffers-when-debugging-with-neovim-dap-plugin/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Use Open Buffers When Debugging With Neovim&amp;rsquo;s DAP Plugin&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I had an issue that whilst debugging my Golang tests in Neovim, the buffer I was focusing on would always change to
the breakpoint. Even when the buffer was open and visible already, say I had the code with the breakpoint on the left
buffer and the tests I was starting the debugger from on the right buffer.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Use Open Buffers When Debugging With Neovim&rsquo;s DAP Plugin</strong></p>
<p>I had an issue that whilst debugging my Golang tests in Neovim, the buffer I was focusing on would always change to
the breakpoint. Even when the buffer was open and visible already, say I had the code with the breakpoint on the left
buffer and the tests I was starting the debugger from on the right buffer.</p>
<p>You can see the example belows:</p>
<p><img
        loading="lazy"
        src="/posts/2023-12-24-til-how-to-use-open-buffers-when-debugging-with-neovim-dap-plugin/images/example.png"
        type=""
        alt="Example Setup"
        
      /></p>
<p>When I start the DAP debugger on the right hand side, by using it to debug the nearest tests, the buffer will change
to the breakpointed line. However I want it to use the open buffer on the left because it is already open.</p>
<p>To do this we need to update our Neovim options: <code>vim.o.switchbuf = &quot;useopen,uselast&quot;</code>. This will now behave as we
want. Note <code>uselast</code>, here is the default value for this option. You can read more about by typing <code>:help 'switchbuf</code>.</p>
<p>That&rsquo;s it! We can now debugger our code and keep the layout we have.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix a NTFS Drive on NixOS</title>
      <link>https://haseebmajid.dev/posts/2023-12-06-til-how-to-ntfs-drive-on-nixos/</link>
      <pubDate>Wed, 06 Dec 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-12-06-til-how-to-ntfs-drive-on-nixos/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to NTFS Drive on NixOS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I was trying to open an NTFS drive on my NixOS machine; however, the drive was corrupted. So I did the
following to fix the drive.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nix-shell -p ntfs3g
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ntfsfix /dev/sda1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where &lt;code&gt;/dev/sda1&lt;/code&gt; is the broken drive. This was enough for me to be able to mount the drive and access the files on it.
I didn&amp;rsquo;t need to fix it on a Window machine.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to NTFS Drive on NixOS</strong></p>
<p>Recently, I was trying to open an NTFS drive on my NixOS machine; however, the drive was corrupted. So I did the
following to fix the drive.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nix-shell -p ntfs3g
</span></span><span class="line"><span class="cl">ntfsfix /dev/sda1
</span></span></code></pre></div><p>Where <code>/dev/sda1</code> is the broken drive. This was enough for me to be able to mount the drive and access the files on it.
I didn&rsquo;t need to fix it on a Window machine.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Append to a Config Option String in Nix</title>
      <link>https://haseebmajid.dev/posts/2023-12-01-til-how-to-append-to-a-config-option-string-in-nix/</link>
      <pubDate>Fri, 01 Dec 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-12-01-til-how-to-append-to-a-config-option-string-in-nix/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Append to a Config Option String in Nix&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently on my laptop I had to add some extra config settings to my Hyprland config. Rather than polluting my
&lt;code&gt;hyprland.nix&lt;/code&gt; file with if, else depending on the host. I wanted to add the extra config in the &lt;code&gt;home.nix&lt;/code&gt; of the
host. So it&amp;rsquo;s contained within that host. Where my &lt;code&gt;home.nix&lt;/code&gt; is the entry point for my
home-manager config for that host.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Append to a Config Option String in Nix</strong></p>
<p>Recently on my laptop I had to add some extra config settings to my Hyprland config. Rather than polluting my
<code>hyprland.nix</code> file with if, else depending on the host. I wanted to add the extra config in the <code>home.nix</code> of the
host. So it&rsquo;s contained within that host. Where my <code>home.nix</code> is the entry point for my
home-manager config for that host.</p>
<p>My <code>hyprland.nix</code> looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="n">wayland</span><span class="o">.</span><span class="n">windowManager</span><span class="o">.</span><span class="n">hyprland</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">extraConfig</span> <span class="o">=</span> <span class="s1">&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">     input {
</span></span></span><span class="line"><span class="cl"><span class="s1">        kb_layout = gb
</span></span></span><span class="line"><span class="cl"><span class="s1">        touchpad {
</span></span></span><span class="line"><span class="cl"><span class="s1">            disable_while_typing=false
</span></span></span><span class="line"><span class="cl"><span class="s1">        }
</span></span></span><span class="line"><span class="cl"><span class="s1">     }
</span></span></span><span class="line"><span class="cl"><span class="s1">  &#39;&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>I want to add some extra config to the <code>extraConfig</code> option/attribute of this attribute set.
Then in my <code>home.nix</code> I added the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="n">wayland</span><span class="o">.</span><span class="n">windowManager</span><span class="o">.</span><span class="n">hyprland</span><span class="o">.</span><span class="n">extraConfig</span> <span class="o">=</span> <span class="n">lib</span><span class="o">.</span><span class="n">mkAfter</span> <span class="s1">&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">  exec-once = /usr/libexec/geoclue-2.0/demos/agent
</span></span></span><span class="line"><span class="cl"><span class="s1">  exec-once = warp-taskbar
</span></span></span><span class="line"><span class="cl"><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">  bind=,XF86Launch5,exec,/usr/local/bin/swaylock -S
</span></span></span><span class="line"><span class="cl"><span class="s1">  bind=,XF86Launch4,exec,/usr/local/bin/swaylock -S
</span></span></span><span class="line"><span class="cl"><span class="s1">  bind=SUPER,backspace,exec,/usr/local/bin/swaylock -S
</span></span></span><span class="line"><span class="cl"><span class="s1">&#39;&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>In this case we want to start some processes on this host, like showing warp in my taskbar.
The key line here being <code>lib.mkAfter</code>. Which will append the content after the existing config options we defined in <code>hyprland.nix</code></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Set the Path Variable When Using Ubuntu With Nix (Home Manager)</title>
      <link>https://haseebmajid.dev/posts/2023-11-25-til-how-to-set-the-path-variable-when-using-ubuntu-with-nix-home-manager/</link>
      <pubDate>Sat, 25 Nov 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-11-25-til-how-to-set-the-path-variable-when-using-ubuntu-with-nix-home-manager/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Set the Path Variable When Using Ubuntu With Nix (Home Manager)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As per some of my recent articles, you will be aware I am using Hyprland (tiling manager) on Ubuntu and managing the
config using nix (home-manager). I was having issues where for some reason it wouldn&amp;rsquo;t set the &lt;code&gt;PATH&lt;/code&gt; variable correctly.&lt;/p&gt;
&lt;p&gt;On my NixOS machine, the following would be fine:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;bind&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;,XF86AudioRaiseVolume,exec, volume --inc
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;bind&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;,XF86AudioLowerVolume,exec, volume --dec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, on Ubuntu I needed to provide the full path:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Set the Path Variable When Using Ubuntu With Nix (Home Manager)</strong></p>
<p>As per some of my recent articles, you will be aware I am using Hyprland (tiling manager) on Ubuntu and managing the
config using nix (home-manager). I was having issues where for some reason it wouldn&rsquo;t set the <code>PATH</code> variable correctly.</p>
<p>On my NixOS machine, the following would be fine:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">bind</span><span class="o">=</span>,XF86AudioRaiseVolume,exec, volume --inc
</span></span><span class="line"><span class="cl"><span class="nv">bind</span><span class="o">=</span>,XF86AudioLowerVolume,exec, volume --dec
</span></span></code></pre></div><p>However, on Ubuntu I needed to provide the full path:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">bind</span><span class="o">=</span>,XF86AudioRaiseVolume,exec, <span class="si">${</span><span class="nv">volume</span><span class="si">}</span>/bin/volume --inc
</span></span></code></pre></div><p>So in the Hyprland config it would look like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">bind</span><span class="o">=</span>,XF86AudioRaiseVolume,exec, /nix/store/q1wm84g65smaq4agq7zp40q57x3534ni-volume/bin/volume --inc
</span></span></code></pre></div><p>It was because the session was being started by GDM (gnome), and the <code>PATH</code> variable was not being set properly.
In Wayland GDM picks up environment variables from <code>~/.config/environment.d/envvars.conf</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> so we can add it here.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ bat ~/.config/environment.d/envvars.conf --plain
</span></span><span class="line"><span class="cl"><span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$PATH</span><span class="s2">:/home/haseebmajid/.nix-profile/bin&#34;</span>
</span></span></code></pre></div><p>Replace <code>haseebmajid</code> with your username (or I guess <code>$HOME</code> should work). This means when we run scripts now, it will
source them from this nix-profile folder. Where the binaries get symlinked, including the volume script above. So
now you don&rsquo;t need to specify the full path (though maybe you should 🤷)</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/dotfiles/-/blob/9561a21fed329f25802290621a54588e314af1ee/home-manager/desktops/wms/hyprland.nix">Hyprland Config</a></li>
<li><a href="https://old.reddit.com/r/NixOS/comments/17rilhc/hyprlandsway_needs_full_path_to_scripts_on/">Reddit Thread</a></li>
<li><a href="https://discourse.nixos.org/t/hyprland-sway-need-full-path-to-scripts-on-non-nixos/35233">Discourse Thread</a></li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://wiki.archlinux.org/title/environment_variables#Graphical_environment">https://wiki.archlinux.org/title/environment_variables#Graphical_environment</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Title Your Terminals When Running Tmux</title>
      <link>https://haseebmajid.dev/posts/2023-11-22-til-how-to-title-your-terminals-when-running-tmux/</link>
      <pubDate>Wed, 22 Nov 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-11-22-til-how-to-title-your-terminals-when-running-tmux/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Title Your Terminals When Running Tmux&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have been tmux with the foot terminal and when trying to share my screen I couldn&amp;rsquo;t work out which terminal to share
based on the name. Since they are running tmux, all the terminals were titled &lt;code&gt;terminal - t&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To fix this and name it after what is running (and where) in tmux, i.e. &lt;code&gt;foot blog/nvim&lt;/code&gt;. We can do this by adding the
following to our tmux config:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Title Your Terminals When Running Tmux</strong></p>
<p>I have been tmux with the foot terminal and when trying to share my screen I couldn&rsquo;t work out which terminal to share
based on the name. Since they are running tmux, all the terminals were titled <code>terminal - t</code>.</p>
<p>To fix this and name it after what is running (and where) in tmux, i.e. <code>foot blog/nvim</code>. We can do this by adding the
following to our tmux config:</p>
<pre tabindex="0"><code class="language-tmux" data-lang="tmux">set-option -g set-titles on
set-option -g set-titles-string &#34;#S / #W&#34;
</code></pre><p>Here, the <code>#S</code> is the session name and <code>#W</code> the window name; hence, we get something like the above. Though you could use
lots of other different formats <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<p>This is enough for me to figure out which window to share.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://github.com/tmux/tmux/wiki/Formats">https://github.com/tmux/tmux/wiki/Formats</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Start Gnome Wayland Session From TTY</title>
      <link>https://haseebmajid.dev/posts/2023-11-21-til-how-to-start-gnome-wayland-session-from-tty/</link>
      <pubDate>Tue, 21 Nov 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-11-21-til-how-to-start-gnome-wayland-session-from-tty/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Start Gnome Wayland Session From TTY&lt;/strong&gt;&lt;/p&gt;
&lt;details
  class=&#34;notice info&#34;
  open=&#34;true&#34;
&gt;
    &lt;summary class=&#34;notice-title&#34;&gt;Better Version&lt;/summary&gt;
  
  &lt;p&gt;veganomy posted a better version: &lt;a href=&#34;https://github.com/hmajid2301/blog/issues/2&#34;&gt;https://github.com/hmajid2301/blog/issues/2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Copy &lt;code&gt;org.gnome.Shell.desktop&lt;/code&gt; file locally:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cp /usr/share/applications/org.gnome.Shell.desktop ~/.local/share/applications/org.gnome.Shell-Wayland.desktop
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Edit it so that it so that it runs &lt;code&gt;gnome-shell&lt;/code&gt; as a wayland compositor:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ less ~/.local/share/applications/org.gnome.Shell-Wayland.desktop
...
Exec=/usr/bin/gnome-shell --wayland
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copy &lt;code&gt;gnome.session&lt;/code&gt; file locally:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cp /usr/share/gnome-session/sessions/gnome.session ~/.config/gnome-session/sessions/gnome-wayland.session
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Edit it to use &lt;code&gt;org.gnome.Shell-Wayland&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ less ~/.config/gnome-session/sessions/gnome-wayland.session
...
RequiredComponents=org.gnome.Shell-Wayland;gnome-settings-daemon;
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now create an executable &lt;code&gt;~/.local/bin/gnome&lt;/code&gt; :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
#!/bin/sh

[ -r /bin/gnome-session ] &amp;amp;&amp;amp; {
	export \
		EGL_PLATFORM=wayland \
		GDK_BACKEND=wayland \
		XDG_SESSION_DESKTOP=gnome
	/bin/gnome-session --session=gnome-wayland
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Make sure this directory is in your &lt;code&gt;~/.bash_profile&lt;/code&gt; $PATH : &lt;code&gt;export PATH=~/.local/bin:$PATH&lt;/code&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Start Gnome Wayland Session From TTY</strong></p>
<details
  class="notice info"
  open="true"
>
    <summary class="notice-title">Better Version</summary>
  
  <p>veganomy posted a better version: <a href="https://github.com/hmajid2301/blog/issues/2">https://github.com/hmajid2301/blog/issues/2</a></p>
<p>Copy <code>org.gnome.Shell.desktop</code> file locally:</p>
<pre tabindex="0"><code>$ cp /usr/share/applications/org.gnome.Shell.desktop ~/.local/share/applications/org.gnome.Shell-Wayland.desktop
</code></pre><p>Edit it so that it so that it runs <code>gnome-shell</code> as a wayland compositor:</p>
<pre tabindex="0"><code>$ less ~/.local/share/applications/org.gnome.Shell-Wayland.desktop
...
Exec=/usr/bin/gnome-shell --wayland
...
</code></pre><p>Copy <code>gnome.session</code> file locally:</p>
<pre tabindex="0"><code>$ cp /usr/share/gnome-session/sessions/gnome.session ~/.config/gnome-session/sessions/gnome-wayland.session
</code></pre><p>Edit it to use <code>org.gnome.Shell-Wayland</code>:</p>
<pre tabindex="0"><code>$ less ~/.config/gnome-session/sessions/gnome-wayland.session
...
RequiredComponents=org.gnome.Shell-Wayland;gnome-settings-daemon;
...
</code></pre><p>Now create an executable <code>~/.local/bin/gnome</code> :</p>
<pre tabindex="0"><code>
#!/bin/sh

[ -r /bin/gnome-session ] &amp;&amp; {
	export \
		EGL_PLATFORM=wayland \
		GDK_BACKEND=wayland \
		XDG_SESSION_DESKTOP=gnome
	/bin/gnome-session --session=gnome-wayland
}
</code></pre><p>Make sure this directory is in your <code>~/.bash_profile</code> $PATH : <code>export PATH=~/.local/bin:$PATH</code></p>
<p>Now you can run a wayland session through TTY :</p>
<pre tabindex="0"><code>$ gnome
</code></pre>
</details>

<p>Recently, I moved to Hyprland on Ubuntu. I wanted to start gnome in another TTY (teletype). It was more effort to find than I expected:</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"># Go to teletype</span>
</span></span><span class="line"><span class="cl">CTRL+ALT+1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">dbus-run-session -- gnome-shell --display-server --wayland
</span></span></code></pre></div><p>That&rsquo;s it, short and sweet, this post! You now started gnome in a Wayland session.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Debug a Test in Golang With Build Tags in Neovim</title>
      <link>https://haseebmajid.dev/posts/2023-11-16-til-how-to-debug-a-test-in-golang-with-build-tags-in-neovim/</link>
      <pubDate>Thu, 16 Nov 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-11-16-til-how-to-debug-a-test-in-golang-with-build-tags-in-neovim/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Debug a Test in Golang With Build Tags in Neovim&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I was having issues with my debugger today (well technically yesterday because I am publishing this a day later to spread
out my blog posts but same difference) and it took me a few hours to realise what was going on. In my case, I was
trying to debug a test written in Golang using &lt;code&gt;nvim-dap-go&lt;/code&gt; on Neovim.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Debug a Test in Golang With Build Tags in Neovim</strong></p>
<p>I was having issues with my debugger today (well technically yesterday because I am publishing this a day later to spread
out my blog posts but same difference) and it took me a few hours to realise what was going on. In my case, I was
trying to debug a test written in Golang using <code>nvim-dap-go</code> on Neovim.</p>
<p>The reason the test was failing  because the test file had build tags so delve (the debugger) couldn&rsquo;t compile
the file, i.e. using the unit build tag in the example below.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="cp">//go:build unit</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// +build unit</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="kn">package</span><span class="w"> </span><span class="nx">options_test</span><span class="w">
</span></span></span></code></pre></div><p>When we set up the <code>dag-go</code> plugin, we need to pass an extra field called <code>build_flags</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">lua</span> <span class="n">require</span><span class="p">(</span><span class="s1">&#39;dap-go&#39;</span><span class="p">).</span><span class="n">setup</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">delve</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line hl"><span class="cl">    <span class="n">build_flags</span> <span class="o">=</span> <span class="s2">&#34;-tags=unit,integration,e2e&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Replace the above with the tags you use! If you are using NixVim you should be able to do something like this <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">programs</span><span class="o">.</span><span class="n">nixvim</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">plugins</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">dap</span><span class="o">.</span><span class="n">extensions</span><span class="o">.</span><span class="n">dap-go</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">delve</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="n">path</span> <span class="o">=</span> <span class="s2">&#34;</span><span class="si">${</span><span class="n">pkgs</span><span class="o">.</span><span class="n">delve</span><span class="si">}</span><span class="s2">/bin/dlv&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">          <span class="n">buildFlags</span> <span class="o">=</span> <span class="s2">&#34;-tags=unit,integration,e2e&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Then I have a keybinding to debug the nearest test like so, again using NixVim.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">action</span> <span class="o">=</span> <span class="s2">&#34;&lt;cmd&gt; lua require(&#39;dap-go&#39;).debug_test()&lt;CR&gt;&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">key</span> <span class="o">=</span> <span class="s2">&#34;&lt;leader&gt;td&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">options</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">desc</span> <span class="o">=</span> <span class="s2">&#34;Debug Nearest (Go)&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">mode</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;n&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span></code></pre></div><p>in lua:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;leader&gt;td&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;cmd&gt;lua require(&#39;dap-go&#39;).debug_test()&lt;CR&gt;&#34;</span><span class="p">)</span>
</span></span></code></pre></div><div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>After this PR is merged, <a href="https://github.com/nix-community/nixvim/pull/703">https://github.com/nix-community/nixvim/pull/703</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Install Neovim Nightly Using Nix Home Manager (and NixVim)</title>
      <link>https://haseebmajid.dev/posts/2023-11-15-til-how-to-install-neovim-nightly-using-nix-home-manager/</link>
      <pubDate>Wed, 15 Nov 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-11-15-til-how-to-install-neovim-nightly-using-nix-home-manager/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Install Neovim Nightly Using Nix Home Manager (and NixVim)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I wanted to install the nightly version of Neovim (version 0.10) because it supports inlay hints.
However, on nixpkgs the latest version of Neovim as of writing is 0.9.4. So how can we get the nightly release?
Using nix/home-manager.&lt;/p&gt;
&lt;p&gt;Simple, we can use an overlay that will add the Neovim nightly package with the nightly. Assuming we are using nix flakes.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Install Neovim Nightly Using Nix Home Manager (and NixVim)</strong></p>
<p>Recently, I wanted to install the nightly version of Neovim (version 0.10) because it supports inlay hints.
However, on nixpkgs the latest version of Neovim as of writing is 0.9.4. So how can we get the nightly release?
Using nix/home-manager.</p>
<p>Simple, we can use an overlay that will add the Neovim nightly package with the nightly. Assuming we are using nix flakes.</p>
<p>Add the nightly Neovim as an input:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"> <span class="n">inputs</span><span class="o">.</span><span class="n">neovim-nightly-overlay</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;github:nix-community/neovim-nightly-overlay&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>Then add the actual overlay, I do this in my home manager config <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl">  <span class="n">nixpkgs</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">overlays</span> <span class="o">=</span>  <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="n">inputs</span><span class="o">.</span><span class="n">neovim-nightly-overlay</span><span class="o">.</span><span class="n">overlay</span>
</span></span><span class="line"><span class="cl">    <span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span></code></pre></div><p>Then in another module we can do something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">home</span><span class="o">.</span><span class="n">packages</span> <span class="o">=</span> <span class="k">with</span> <span class="n">pkgs</span> <span class="p">[</span><span class="n">neovim-nightly</span><span class="p">]</span>
</span></span></code></pre></div><p>or if you are using NixVim <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> like me:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">programs</span><span class="o">.</span><span class="n">nixvim</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">extraPlugins</span> <span class="o">=</span> <span class="k">with</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">vimPlugins</span><span class="p">;</span> <span class="p">[</span> <span class="n">plenary-nvim</span> <span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="n">package</span> <span class="o">=</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">neovim-nightly</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://gitlab.com/hmajid2301/dotfiles/-/blob/ed8f60b6f27980508161d337e0a75ebb655cb19b/home-manager/default.nix#L52">https://gitlab.com/hmajid2301/dotfiles/-/blob/ed8f60b6f27980508161d337e0a75ebb655cb19b/home-manager/default.nix#L52</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><a href="https://github.com/nix-community/nixvim">https://github.com/nix-community/nixvim</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Set Network Manager Priority to Use Wired Connection Over WIFI</title>
      <link>https://haseebmajid.dev/posts/2023-11-10-how-to-set-network-manager-priority-to-use-wired-connection-over-wifi/</link>
      <pubDate>Fri, 10 Nov 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-11-10-how-to-set-network-manager-priority-to-use-wired-connection-over-wifi/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Set Network Manager Priority to Use Wired Connection Over Wi-Fi&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you use network manager on Linux and have both Wi-Fi and wired connection. You may want to prefer using
a wired connection over Wi-Fi, due to stability. To do open the &lt;code&gt;nm-connection-editor&lt;/code&gt;, if you are using Nix, you can
download it from nixpkgs like usual.&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2023-11-10-how-to-set-network-manager-priority-to-use-wired-connection-over-wifi/images/priority.png&#34;
        type=&#34;&#34;
        alt=&#34;Network Manager Priority&#34;
        
      /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Higher number means higher priority.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So for our wired connection I set the priority to &lt;code&gt;100&lt;/code&gt; (it was previously -1) and then for our Wi-Fi connection
I set the priority to &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Set Network Manager Priority to Use Wired Connection Over Wi-Fi</strong></p>
<p>If you use network manager on Linux and have both Wi-Fi and wired connection. You may want to prefer using
a wired connection over Wi-Fi, due to stability. To do open the <code>nm-connection-editor</code>, if you are using Nix, you can
download it from nixpkgs like usual.</p>
<p><img
        loading="lazy"
        src="/posts/2023-11-10-how-to-set-network-manager-priority-to-use-wired-connection-over-wifi/images/priority.png"
        type=""
        alt="Network Manager Priority"
        
      /></p>
<blockquote>
<p>Higher number means higher priority.</p>
</blockquote>
<p>So for our wired connection I set the priority to <code>100</code> (it was previously -1) and then for our Wi-Fi connection
I set the priority to <code>1</code>.</p>
<p>That&rsquo;s it! We should now see network manager prefer to use Ethernet over Wi-Fi.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Use Clipboard Data as File Input in Bash</title>
      <link>https://haseebmajid.dev/posts/2023-11-01-til-how-to-use-clipboard-data-as-file-input-in-bash/</link>
      <pubDate>Wed, 01 Nov 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-11-01-til-how-to-use-clipboard-data-as-file-input-in-bash/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Use Clipboard Data as File Input in Bash&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I wanted to run a bash script where it needed to receive a JSON file as input. However, the JSON I had
was taken from somewhere on the internet. In this case, it was taking a JSON blob and converting it to a nix attribute
set. However, I didn&amp;rsquo;t want to save the contents to a file beforehand.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Use Clipboard Data as File Input in Bash</strong></p>
<p>Recently, I wanted to run a bash script where it needed to receive a JSON file as input. However, the JSON I had
was taken from somewhere on the internet. In this case, it was taking a JSON blob and converting it to a nix attribute
set. However, I didn&rsquo;t want to save the contents to a file beforehand.</p>
<p>This is the command here as an example, note the <code>/dev/stdin</code> which acts as file like object for us.</p>
<pre tabindex="0"><code>wl-paste | json2nix /dev/stdin
</code></pre><p>So <code>wl-paste</code> returns the contents of our clipboard (our JSON). Then we pipe that over to our <code>json2nix</code> script which
expects a file. We can pretend to have a file by using the <code>/dev/stdin</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://jameshfisher.com/2018/03/31/dev-stdout-stdin/">https://jameshfisher.com/2018/03/31/dev-stdout-stdin/</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix Networking Issues in a Libvirt VM and Mullvad VPN</title>
      <link>https://haseebmajid.dev/posts/2023-10-21-til-how-to-fix-networking-issues-in-a-libvirt-vm-and-mullvad-vpn/</link>
      <pubDate>Sat, 21 Oct 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-10-21-til-how-to-fix-networking-issues-in-a-libvirt-vm-and-mullvad-vpn/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix Networking Issues in a Libvirt VM and Mullvad VPN&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently, I was trying to run a libvirt virtual machine, created using &lt;a href=&#34;https://virt-manager.org/&#34;&gt;virt-manager&lt;/a&gt;.
The VM was running NixOS and somehow no matter what I did it would not connect to the internet.&lt;/p&gt;
&lt;p&gt;I was running Mullvad as my VPN, and it turned out this was the app causing issues, I had to turn on
&lt;code&gt;Local network share&lt;/code&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Like in the photo below:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix Networking Issues in a Libvirt VM and Mullvad VPN</strong></p>
<p>Recently, I was trying to run a libvirt virtual machine, created using <a href="https://virt-manager.org/">virt-manager</a>.
The VM was running NixOS and somehow no matter what I did it would not connect to the internet.</p>
<p>I was running Mullvad as my VPN, and it turned out this was the app causing issues, I had to turn on
<code>Local network share</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. Like in the photo below:</p>
<p><img
        loading="lazy"
        src="/posts/2023-10-21-til-how-to-fix-networking-issues-in-a-libvirt-vm-and-mullvad-vpn/images/vpn.png"
        type=""
        alt="VPN"
        
      /></p>
<p>That&rsquo;s It! Simple fix that took me longer to work than I&rsquo;d like to admit.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://mullvad.net/en/help/#29">https://mullvad.net/en/help/#29</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Disable Linters in Golangci Lint for Test Files</title>
      <link>https://haseebmajid.dev/posts/2023-10-10-til-how-to-disable-linters-in-golangci-lint-for-test-files/</link>
      <pubDate>Tue, 10 Oct 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-10-10-til-how-to-disable-linters-in-golangci-lint-for-test-files/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Disable Linters in Golangci Lint for Test Files&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Today (for once), I ran &lt;code&gt;golangci-lint run&lt;/code&gt; and it failed on CI with the following error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;internal/options/parser_test.go:13: Function &lt;span class=&#34;s1&#34;&gt;&amp;#39;TestParse&amp;#39;&lt;/span&gt; is too long &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;69&lt;/span&gt; &amp;gt; 60&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;funlen&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;func TestParse&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;t *testing.T&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;task: Failed to run task &lt;span class=&#34;s2&#34;&gt;&amp;#34;lint&amp;#34;&lt;/span&gt;: &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; status &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where my &lt;code&gt;.golangci.yml&lt;/code&gt; file looked like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;5m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;skip-dirs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;direnv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;linters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;bodyclose&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;dogsled&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;dupl&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;errcheck&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;exportloopref&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;funlen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;gochecknoinits&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;goconst&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;gocritic&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;gocyclo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;gofmt&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;goimports&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;gomnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;goprintffuncname&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;gosec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;gosimple&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;govet&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;ineffassign&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;lll&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;misspell&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;nakedret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;noctx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;nolintlint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;revive&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;staticcheck&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;stylecheck&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;typecheck&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;unconvert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;unparam&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;unused&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;whitespace&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So basically we want the ability to turn off &lt;code&gt;funlen&lt;/code&gt; for our tests (and other linters). Because we don&amp;rsquo;t mind
if some of our test functions get a big long with different sub-tests.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Disable Linters in Golangci Lint for Test Files</strong></p>
<p>Today (for once), I ran <code>golangci-lint run</code> and it failed on CI with the following error:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">internal/options/parser_test.go:13: Function <span class="s1">&#39;TestParse&#39;</span> is too long <span class="o">(</span><span class="m">69</span> &gt; 60<span class="o">)</span> <span class="o">(</span>funlen<span class="o">)</span>
</span></span><span class="line"><span class="cl">func TestParse<span class="o">(</span>t *testing.T<span class="o">)</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">task: Failed to run task <span class="s2">&#34;lint&#34;</span>: <span class="nb">exit</span> status <span class="m">1</span>
</span></span></code></pre></div><p>Where my <code>.golangci.yml</code> file looked like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">run</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">5m</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">skip-dirs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">direnv</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="nt">linters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">enable</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">bodyclose</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">dogsled</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">dupl</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">errcheck</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">exportloopref</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">funlen</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">gochecknoinits</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">goconst</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">gocritic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">gocyclo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">gofmt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">goimports</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">gomnd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">goprintffuncname</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">gosec</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">gosimple</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">govet</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">ineffassign</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">lll</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">misspell</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">nakedret</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">noctx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">nolintlint</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">revive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">staticcheck</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">stylecheck</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">typecheck</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">unconvert</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">unparam</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">unused</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">whitespace</span><span class="w">
</span></span></span></code></pre></div><p>So basically we want the ability to turn off <code>funlen</code> for our tests (and other linters). Because we don&rsquo;t mind
if some of our test functions get a big long with different sub-tests.</p>
<p>So to disable some linters for our test files we can do something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">linters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">enable</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">bodyclose</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># ...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="nt">issues</span><span class="p">:</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">  </span><span class="nt">exclude-rules</span><span class="p">:</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">    </span>- <span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">_test.go</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">      </span><span class="nt">linters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">        </span>- <span class="l">funlen</span><span class="w">
</span></span></span></code></pre></div><p>That&rsquo;s it! For once a TIL, that was written on the same day as I learned it (or re-learnt it)</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Colour Dap Breakpointed Line in Neovim</title>
      <link>https://haseebmajid.dev/posts/2023-10-07-til-how-to-colour-dap-breakpointed-line-in-neovim/</link>
      <pubDate>Sat, 07 Oct 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-10-07-til-how-to-colour-dap-breakpointed-line-in-neovim/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Colour Dap Breakpointed Line in Neovim&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I wanted to change the background colour of the line when it was stopped during debugging using DAP with neovim.
To make it easier to see where we are currently breakpointed.&lt;/p&gt;
&lt;p&gt;We already have a highlight group called &lt;code&gt;DapStopped&lt;/code&gt;. Which in my case is defined as:
&lt;code&gt;DapStopped = { bg = C.grey }&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Then we need to assign the custom highlight group, the key bit being &lt;code&gt;linehl&lt;/code&gt; for our use case.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Colour Dap Breakpointed Line in Neovim</strong></p>
<p>I wanted to change the background colour of the line when it was stopped during debugging using DAP with neovim.
To make it easier to see where we are currently breakpointed.</p>
<p>We already have a highlight group called <code>DapStopped</code>. Which in my case is defined as:
<code>DapStopped = { bg = C.grey }</code>.</p>
<p>Then we need to assign the custom highlight group, the key bit being <code>linehl</code> for our use case.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">require</span><span class="p">(</span><span class="s2">&#34;dap&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">local</span> <span class="n">sign</span> <span class="o">=</span> <span class="n">vim.fn</span><span class="p">.</span><span class="n">sign_define</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">sign</span><span class="p">(</span><span class="s2">&#34;DapBreakpoint&#34;</span><span class="p">,</span> <span class="p">{</span> <span class="n">text</span> <span class="o">=</span> <span class="s2">&#34;●&#34;</span><span class="p">,</span> <span class="n">texthl</span> <span class="o">=</span> <span class="s2">&#34;DapBreakpoint&#34;</span><span class="p">,</span> <span class="n">linehl</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="n">numhl</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="n">sign</span><span class="p">(</span><span class="s2">&#34;DapBreakpointCondition&#34;</span><span class="p">,</span> <span class="p">{</span> <span class="n">text</span> <span class="o">=</span> <span class="s2">&#34;●&#34;</span><span class="p">,</span> <span class="n">texthl</span> <span class="o">=</span> <span class="s2">&#34;DapBreakpointCondition&#34;</span><span class="p">,</span> <span class="n">linehl</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="n">numhl</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="n">sign</span><span class="p">(</span><span class="s2">&#34;DapLogPoint&#34;</span><span class="p">,</span> <span class="p">{</span> <span class="n">text</span> <span class="o">=</span> <span class="s2">&#34;◆&#34;</span><span class="p">,</span> <span class="n">texthl</span> <span class="o">=</span> <span class="s2">&#34;DapLogPoint&#34;</span><span class="p">,</span> <span class="n">linehl</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="n">numhl</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">})</span>
</span></span><span class="line hl"><span class="cl"><span class="n">sign</span><span class="p">(</span><span class="s1">&#39;DapStopped&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="n">text</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">texthl</span><span class="o">=</span><span class="s1">&#39;DapStopped&#39;</span><span class="p">,</span> <span class="n">linehl</span><span class="o">=</span><span class="s1">&#39;DapStopped&#39;</span><span class="p">,</span> <span class="n">numhl</span><span class="o">=</span> <span class="s1">&#39;DapStopped&#39;</span> <span class="p">})</span>
</span></span></code></pre></div><p>Then we start the debugger and it stops at a breakpoint line it looks something like in the photo below.</p>
<p><img
        loading="lazy"
        src="/posts/2023-10-07-til-how-to-colour-dap-breakpointed-line-in-neovim/images/debug.png"
        type=""
        alt="Debugging"
        
      /></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix Package Binary Collisions on Nix</title>
      <link>https://haseebmajid.dev/posts/2023-10-02-til-how-to-fix-package-binary-collisions-on-nix/</link>
      <pubDate>Mon, 02 Oct 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-10-02-til-how-to-fix-package-binary-collisions-on-nix/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix Package Binary Collisions on Nix&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I wanted to use &lt;a href=&#34;https://www.gnu.org/software/parallel/&#34;&gt;GNU parallel&lt;/a&gt;, a nifty little tool we can use
to run tasks in parallel, shock horror I know. I already have the &lt;code&gt;moreutils&lt;/code&gt; package installed using nix (home-manager).&lt;/p&gt;
&lt;p&gt;So I added this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;packages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pkgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;parallel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;moreutils&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I ran the home manager switch like usual, I got the following error.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;error: builder &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;/nix/store/vh6i81xhf6pvybdpall8z8l8y0i6mr8p-home-manager-path.drv&amp;#39;&lt;/span&gt; failed with &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; code 25&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       last &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; log lines:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;gt; error: collision between &lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;/nix/store/slkylri9sbn4w7paaixzc5wj6cwfk83m-moreutils-0.67/bin/parallel&lt;span class=&#34;s1&#34;&gt;&amp;#39; and `/nix/store/fjpnw99zvx2f910s016jrmybc5jxirpn-parallel-20230822/bin/parallel&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       For full logs, run &lt;span class=&#34;s1&#34;&gt;&amp;#39;nix log /nix/store/vh6i81xhf6pvybdpall8z8l8y0i6mr8p-home-manager-path.drv&amp;#39;&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;error: &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; dependencies of derivation &lt;span class=&#34;s1&#34;&gt;&amp;#39;/nix/store/m4p56x5lgjfpvdy0xjrbk981sfchpl8c-home-manager-generation.drv&amp;#39;&lt;/span&gt; failed to build
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Because &lt;code&gt;moreutils&lt;/code&gt; also have a binary called parallel. How do we tell Nix to overwrite the moreutils binary and use
the one in the &lt;code&gt;parallel&lt;/code&gt; packages?  Simple by using &lt;code&gt;lib.hiPrio&lt;/code&gt; like so:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix Package Binary Collisions on Nix</strong></p>
<p>Recently I wanted to use <a href="https://www.gnu.org/software/parallel/">GNU parallel</a>, a nifty little tool we can use
to run tasks in parallel, shock horror I know. I already have the <code>moreutils</code> package installed using nix (home-manager).</p>
<p>So I added this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">home</span><span class="o">.</span><span class="n">packages</span> <span class="o">=</span> <span class="k">with</span> <span class="n">pkgs</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line hl"><span class="cl">  <span class="n">parallel</span>
</span></span><span class="line"><span class="cl">  <span class="n">moreutils</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span></code></pre></div><p>Then I ran the home manager switch like usual, I got the following error.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">error: builder <span class="k">for</span> <span class="s1">&#39;/nix/store/vh6i81xhf6pvybdpall8z8l8y0i6mr8p-home-manager-path.drv&#39;</span> failed with <span class="nb">exit</span> code 25<span class="p">;</span>
</span></span><span class="line"><span class="cl">       last <span class="m">1</span> log lines:
</span></span><span class="line"><span class="cl">       &gt; error: collision between <span class="sb">`</span>/nix/store/slkylri9sbn4w7paaixzc5wj6cwfk83m-moreutils-0.67/bin/parallel<span class="s1">&#39; and `/nix/store/fjpnw99zvx2f910s016jrmybc5jxirpn-parallel-20230822/bin/parallel&#39;</span>
</span></span><span class="line"><span class="cl">       For full logs, run <span class="s1">&#39;nix log /nix/store/vh6i81xhf6pvybdpall8z8l8y0i6mr8p-home-manager-path.drv&#39;</span>.
</span></span><span class="line"><span class="cl">error: <span class="m">1</span> dependencies of derivation <span class="s1">&#39;/nix/store/m4p56x5lgjfpvdy0xjrbk981sfchpl8c-home-manager-generation.drv&#39;</span> failed to build
</span></span></code></pre></div><p>Because <code>moreutils</code> also have a binary called parallel. How do we tell Nix to overwrite the moreutils binary and use
the one in the <code>parallel</code> packages?  Simple by using <code>lib.hiPrio</code> like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">home</span><span class="o">.</span><span class="n">packages</span> <span class="o">=</span> <span class="k">with</span> <span class="n">pkgs</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line hl"><span class="cl">  <span class="p">(</span><span class="n">lib</span><span class="o">.</span><span class="n">hiPrio</span> <span class="n">parallel</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">moreutils</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span></code></pre></div><p>This tells Nix to increase the priority of this package you can see
<a href="https://github.com/NixOS/nixpkgs/blob/efdb9b4ee86a3bf3349efa7a23b42cbc18766b90/lib/meta.nix#L52-L69">the code here</a>.</p>
<p>That&rsquo;s it we can still have access to the other binaries moreutils provides like <code>sponge</code> and <code>parallel</code> from parallel
package.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Use fzf.fish History Search</title>
      <link>https://haseebmajid.dev/posts/2023-09-19-til-how-to-use-fzf-fish-history-search/</link>
      <pubDate>Tue, 19 Sep 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-09-19-til-how-to-use-fzf-fish-history-search/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Use fzf.fish History Search&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I use Fish Shell with fzf and &lt;a href=&#34;https://github.com/PatrickF1/fzf.fish&#34;&gt;fish fzf plugin&lt;/a&gt;.
I installed fzf using nix and home-manager:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;programs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fzf&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;enableFishIntegration&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It adds &lt;code&gt;fzf-history-widget&lt;/code&gt; script, which is bound to &lt;code&gt;ctrl+r&lt;/code&gt;, shell reverse history search.
Which we can see when we run this: &lt;code&gt;bind | grep -e fzf-history-widget -e fzf-file-widget&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Whereas I wanted to use the &lt;code&gt;_fzf_search_history&lt;/code&gt; which is made available by that fish fzf plugin.
Now PatrickF1 recommends running the uninstaller script from fzf, but I found another way we can overwrite
the binding by adding the following lines to our &lt;code&gt;fish.config&lt;/code&gt;:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Use fzf.fish History Search</strong></p>
<p>I use Fish Shell with fzf and <a href="https://github.com/PatrickF1/fzf.fish">fish fzf plugin</a>.
I installed fzf using nix and home-manager:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">programs</span><span class="o">.</span><span class="n">fzf</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">enableFishIntegration</span> <span class="o">=</span> <span class="no">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>It adds <code>fzf-history-widget</code> script, which is bound to <code>ctrl+r</code>, shell reverse history search.
Which we can see when we run this: <code>bind | grep -e fzf-history-widget -e fzf-file-widget</code></p>
<p>Whereas I wanted to use the <code>_fzf_search_history</code> which is made available by that fish fzf plugin.
Now PatrickF1 recommends running the uninstaller script from fzf, but I found another way we can overwrite
the binding by adding the following lines to our <code>fish.config</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fish" data-lang="fish"><span class="line"><span class="cl"><span class="nb">bind</span> <span class="se">\c</span>r _fzf_search_history
</span></span><span class="line"><span class="cl"><span class="nb">bind</span> <span class="na">-M</span> insert <span class="se">\c</span>r _fzf_search_history
</span></span></code></pre></div><p>So now when I press <code>ctrl+r</code> in my shell I used to get this (before):</p>
<p><img
        loading="lazy"
        src="/posts/2023-09-19-til-how-to-use-fzf-fish-history-search/images/fzf_original.png"
        type=""
        alt="FZF"
        
      /></p>
<p>but now I get this (after):</p>
<p><img
        loading="lazy"
        src="/posts/2023-09-19-til-how-to-use-fzf-fish-history-search/images/fish_fzf.png"
        type=""
        alt="FZF Fish"
        
      /></p>
<h2 id="appendix">Appendix</h2>
<ul>
<li>[My nix fish shell config](<a href="https://gitlab.com/hmaji%5D(https://gitlab.com/hmajid2301/dotfiles/-/blob/a34417ed452fe068ec4a91fba7ef0a14fca31b76/home-manager/shells/fish.nix#L48-49)">https://gitlab.com/hmaji](https://gitlab.com/hmajid2301/dotfiles/-/blob/a34417ed452fe068ec4a91fba7ef0a14fca31b76/home-manager/shells/fish.nix#L48-49)</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Check if Another Option Is Set in Home Manager (Nix)</title>
      <link>https://haseebmajid.dev/posts/2023-09-10-til-how-to-check-if-another-option-is-set-in-home-manager-nix/</link>
      <pubDate>Sun, 10 Sep 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-09-10-til-how-to-check-if-another-option-is-set-in-home-manager-nix/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Check if Another Option Is Set in Home Manager (Nix)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I was adding sway to my nix config (setup via home-manager). I already had Hyprland config, I wanted both
sway and Hyprland to use my waybar config with some slight differences. So basically I want to check if the current
host machine is using Sway or Hyprland (I am assuming we will only use one).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The main reason for using Sway is my work laptop uses Ubuntu 22.04, It&amp;rsquo;s not easy to run Hyprland on a &amp;ldquo;stable&amp;rdquo; distro like Ubuntu better suited to Arch or NixOS.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Check if Another Option Is Set in Home Manager (Nix)</strong></p>
<p>Recently I was adding sway to my nix config (setup via home-manager). I already had Hyprland config, I wanted both
sway and Hyprland to use my waybar config with some slight differences. So basically I want to check if the current
host machine is using Sway or Hyprland (I am assuming we will only use one).</p>
<blockquote>
<p>The main reason for using Sway is my work laptop uses Ubuntu 22.04, It&rsquo;s not easy to run Hyprland on a &ldquo;stable&rdquo; distro like Ubuntu better suited to Arch or NixOS.</p>
</blockquote>
<p>If sway is enabled include some specific config in my Waybar config else include the Hyprland config. So first of all
I have a file called <code>sway.nix</code> which looks something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wayland</span><span class="o">.</span><span class="n">windowManager</span><span class="o">.</span><span class="n">sway</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">package</span> <span class="o">=</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">swayfx</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># ...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>I then have a host file for my work laptop called <code>curve/home.nix</code> which imports this sway expression:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">imports</span> <span class="o">=</span> <span class="p">[</span> <span class="sr">../../home-manager/desktops/sway.nix</span> <span class="p">];</span>
</span></span></code></pre></div><p>Finally, the main part of this article, let&rsquo;s look at my <code>waybar.nix</code> which is imported by <code>sway.nix</code> (and <code>hyprland.nix</code>) expression, which
Check if sway is enabled (which happens if the <code>sway.nix</code> is imported).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span> <span class="n">config</span><span class="o">,</span> <span class="o">...</span> <span class="p">}:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">programs</span><span class="o">.</span><span class="n">waybar</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">settings</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">modules-left</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;custom/launcher&#34;</span>
</span></span><span class="line hl"><span class="cl">          <span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">config</span><span class="o">.</span><span class="n">wayland</span><span class="o">.</span><span class="n">windowManager</span><span class="o">.</span><span class="n">sway</span><span class="o">.</span><span class="n">enable</span> <span class="o">==</span> <span class="no">true</span>
</span></span><span class="line"><span class="cl">            <span class="k">then</span> <span class="s2">&#34;sway/workspaces&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span> <span class="s2">&#34;hyprland/workspaces&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;custom/currentplayer&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;custom/player&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;custom/audio_idle_inhibitor&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="err">}</span>
</span></span><span class="line"><span class="cl"><span class="err">}</span>
</span></span></code></pre></div><p>In the example above <code>config.wayland.windowManager.sway.enable == true</code>, we just do a simple if statement check to
Decide which Waybar module to show (sway or Hyprland).</p>
<p>That&rsquo;s it! How we can check if other expressions can use attributes set in other expression files.
If you have suggestions to make this cleaner I&rsquo;m all ears! This is not cleanest way to do something like this.
But since these are just my own dotfiles I know I will only use one of Sway or Hyprland on my devices.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Access System in Home Manager Using Flakes</title>
      <link>https://haseebmajid.dev/posts/2023-09-05-til-how-to-access-system-in-home-manager-using-flakes/</link>
      <pubDate>Tue, 05 Sep 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-09-05-til-how-to-access-system-in-home-manager-using-flakes/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Access System in Home Manager Using Flakes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I needed to install devenv using flakes in home-manager. One of the things I needed to pass to was the type
of system to install on i.e. &lt;code&gt;&amp;quot;x86_64-linux&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So as I temp hack I had something like: &lt;code&gt;inputs.devenv.packages.&amp;quot;x86_64-linux&amp;quot;.devenv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However I was able to access the system using the &lt;code&gt;pkgs&lt;/code&gt; attribute like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;pkgs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;packages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;devenv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;packages&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pkgs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;system&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;devenv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where my &lt;code&gt;flake.nix&lt;/code&gt; looks something like:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Access System in Home Manager Using Flakes</strong></p>
<p>Recently I needed to install devenv using flakes in home-manager. One of the things I needed to pass to was the type
of system to install on i.e. <code>&quot;x86_64-linux&quot;</code>.</p>
<p>So as I temp hack I had something like: <code>inputs.devenv.packages.&quot;x86_64-linux&quot;.devenv</code>.</p>
<p>However I was able to access the system using the <code>pkgs</code> attribute like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">inputs</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">pkgs</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">  <span class="o">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">home</span><span class="o">.</span><span class="n">packages</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="n">inputs</span><span class="o">.</span><span class="n">devenv</span><span class="o">.</span><span class="n">packages</span><span class="o">.</span><span class="s2">&#34;</span><span class="si">${</span><span class="n">pkgs</span><span class="o">.</span><span class="n">system</span><span class="si">}</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">devenv</span>
</span></span><span class="line"><span class="cl">  <span class="p">];</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Where my <code>flake.nix</code> looks something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl">  <span class="n">outputs</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">self</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">nixpkgs</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">home-manager</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">    <span class="o">...</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="o">@</span> <span class="n">inputs</span><span class="p">:</span> <span class="k">let</span>
</span></span><span class="line"><span class="cl">  <span class="k">in</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">inherit</span> <span class="n">lib</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">homeConfigurations</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="c1"># Desktops</span>
</span></span><span class="line"><span class="cl">      <span class="n">mesmer</span> <span class="o">=</span> <span class="n">lib</span><span class="o">.</span><span class="n">homeManagerConfiguration</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">modules</span> <span class="o">=</span> <span class="p">[</span><span class="sr">./hosts/mesmer/home.nix</span><span class="p">];</span>
</span></span><span class="line hl"><span class="cl">        <span class="n">pkgs</span> <span class="o">=</span> <span class="n">nixpkgs</span><span class="o">.</span><span class="n">legacyPackages</span><span class="o">.</span><span class="n">x86_64-linux</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">extraSpecialArgs</span> <span class="o">=</span> <span class="p">{</span><span class="k">inherit</span> <span class="n">inputs</span> <span class="n">outputs</span><span class="p">;};</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span></code></pre></div><p>You can see here the system is defined with the pkgs, as I guess we need to know for which architecture we should
build for i.e. amd, arch etc. But yeh thats it! For use within home-manager it seems we can use <code>pkgs.system</code>, to
access the architecture, so we don&rsquo;t need to hardcode it.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix tmux-resurrect on NixOS</title>
      <link>https://haseebmajid.dev/posts/2023-09-01-til-how-to-fix-tmux-resurrect-on-nixos/</link>
      <pubDate>Fri, 01 Sep 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-09-01-til-how-to-fix-tmux-resurrect-on-nixos/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix tmux-resurrect on NixOS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I moved to NixOS I noticed that &lt;a href=&#34;https://github.com/tmux-plugins/tmux-resurrect&#34;&gt; tmux-resurrect &lt;/a&gt; stop restoring
some applications such as &lt;code&gt;man&lt;/code&gt; and &lt;code&gt;nvim&lt;/code&gt;. Like it used to on my Arch machine. I recently found a solution to my
problem (thanks to a lovely chap on the nixos discourse).&lt;/p&gt;
&lt;p&gt;By adding the following lines to our tmux config:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-tmux&#34; data-lang=&#34;tmux&#34;&gt;resurrect_dir=&amp;#34;$HOME/.tmux/resurrect&amp;#34;
set -g @resurrect-dir $resurrect_dir
set -g @resurrect-hook-post-save-all &amp;#39;target=$(readlink -f $resurrect_dir/last); sed &amp;#34;s| --cmd .*-vim-pack-dir||g; s|/etc/profiles/per-user/$USER/bin/||g; s|/home/$USER/.nix-profile/bin/||g&amp;#34; $target | sponge $target&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What this does is it edits the tmux-resurrect file from this:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix tmux-resurrect on NixOS</strong></p>
<p>When I moved to NixOS I noticed that <a href="https://github.com/tmux-plugins/tmux-resurrect"> tmux-resurrect </a> stop restoring
some applications such as <code>man</code> and <code>nvim</code>. Like it used to on my Arch machine. I recently found a solution to my
problem (thanks to a lovely chap on the nixos discourse).</p>
<p>By adding the following lines to our tmux config:</p>
<pre tabindex="0"><code class="language-tmux" data-lang="tmux">resurrect_dir=&#34;$HOME/.tmux/resurrect&#34;
set -g @resurrect-dir $resurrect_dir
set -g @resurrect-hook-post-save-all &#39;target=$(readlink -f $resurrect_dir/last); sed &#34;s| --cmd .*-vim-pack-dir||g; s|/etc/profiles/per-user/$USER/bin/||g; s|/home/$USER/.nix-profile/bin/||g&#34; $target | sponge $target&#39;
</code></pre><p>What this does is it edits the tmux-resurrect file from this:</p>
<pre tabindex="0"><code># bat ~/.tmux/resurrect/last --plain

pane    dotfiles    0   1   :*  0   nvim ~/dotfiles :/home/haseeb/dotfiles  1   nvim    :/home/haseeb/.nix-profile/bin/nvim --cmd lua vim.g.loaded_node_provider=0;vim.g.loaded_perl_provider=0;vim.g.loaded_python_provider=0;vim.g.python3_host_prog=&#39;/nix/store/4n4d0f1xd14gl4pfymdcqb9pmagcyyfj-neovim-0.9.1/bin/nvim-python3&#39;;vim.g.ruby_host_prog=&#39;/nix/store/4n4d0f1xd14gl4pfymdcqb9pmagcyyfj-neovim-0.9.1/bin/nvim-ruby&#39;
</code></pre><p>to this:</p>
<pre tabindex="0"><code># bat ~/.tmux/resurrect/last --plain

pane    dotfiles    0   1   :*  0   nvim ~/dotfiles :/home/haseeb/dotfiles  1   nvim    :nvim
</code></pre><p>NOTE: we are just left with <code>:nvim</code> as the binary to run (from tmux-resurrect perspective).
Then to restore my neovim session we could use a plugin which creates a <code>Session.vim</code> file in the local directory
of that project, that tmux-resurrect can use to restore the actual neovim session rather than just running neovim.</p>
<p>However I don&rsquo;t want to manage session files like that. So I use <a href="https://github.com/rmagatti/auto-session"> <code>auto-session</code> </a>
which checks if a session exists in a specific directory and if it does it automatically restores the last saved session
when neovim opens.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://discourse.nixos.org/t/how-to-get-tmux-resurrect-to-restore-neovim-sessions/30819/2">Discourse Thread</a></li>
<li><a href="https://gitlab.com/hmajid2301/dotfiles/-/blob/06bf4ad267beb6693b941ef51d880e4d0fc1df0a/home-manager/programs/multiplexers/tmux.nix#L136-147">My tmux config</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Colour Neovim Line Numbers</title>
      <link>https://haseebmajid.dev/posts/2023-08-24-til-how-to-colour-neovim-line-numbers/</link>
      <pubDate>Thu, 24 Aug 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-08-24-til-how-to-colour-neovim-line-numbers/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Colour Neovim Line Numbers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I was trying to configure my own neovim config. I wanted the current line I was onto be coloured slighty
differently and also the line number to be white. So it&amp;rsquo;s easier to see the line number and which line I was on.&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2023-08-24-til-how-to-colour-neovim-line-numbers/images/highlight.png&#34;
        type=&#34;&#34;
        alt=&#34;Highlight&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;It was not immediately obvious how to do this and took me long to work out than I&amp;rsquo;d like to admit 😅.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Colour Neovim Line Numbers</strong></p>
<p>Recently I was trying to configure my own neovim config. I wanted the current line I was onto be coloured slighty
differently and also the line number to be white. So it&rsquo;s easier to see the line number and which line I was on.</p>
<p><img
        loading="lazy"
        src="/posts/2023-08-24-til-how-to-colour-neovim-line-numbers/images/highlight.png"
        type=""
        alt="Highlight"
        
      /></p>
<p>It was not immediately obvious how to do this and took me long to work out than I&rsquo;d like to admit 😅.</p>
<p>First we need to create to two highlight groups:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="c1">-- Highlights the line</span>
</span></span><span class="line"><span class="cl"><span class="n">CursorLine</span> <span class="o">=</span> <span class="p">{</span> <span class="n">fg</span> <span class="o">=</span> <span class="s1">&#39;NONE&#39;</span><span class="p">,</span> <span class="n">bg</span> <span class="o">=</span> <span class="n">c.black2</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">-- Highlights the line number</span>
</span></span><span class="line"><span class="cl"><span class="n">CursorLineNr</span> <span class="o">=</span> <span class="p">{</span> <span class="n">fg</span> <span class="o">=</span> <span class="n">c.white</span> <span class="p">},</span>
</span></span></code></pre></div><p>Then in our vim options set the following <code>vim.o.cursorline = true</code> (this is what I was missing, in my case).</p>
<p>Anyways that&rsquo;s it! A really quick post, on something stupid I got stuck on!</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Setup Neovim for Nixlang</title>
      <link>https://haseebmajid.dev/posts/2023-08-06-til-how-to-setup-neovim-for-nixlang/</link>
      <pubDate>Sun, 06 Aug 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-08-06-til-how-to-setup-neovim-for-nixlang/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Setup Neovim for Nixlang&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have been recently using NixOS/home-manager and I have been writing a lot of nixlang. To have my system state
declaratively set up. I have been doing most of this editing in neovim. It took me a bit of time to work out how to get
it set up so there is some basic LSP support and auto-formatting. I created a file called &lt;code&gt;nix.lua&lt;/code&gt; and it looks like this:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Setup Neovim for Nixlang</strong></p>
<p>I have been recently using NixOS/home-manager and I have been writing a lot of nixlang. To have my system state
declaratively set up. I have been doing most of this editing in neovim. It took me a bit of time to work out how to get
it set up so there is some basic LSP support and auto-formatting. I created a file called <code>nix.lua</code> and it looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="kr">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">-- Correctly setup lspconfig for Nix 🚀</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;neovim/nvim-lspconfig&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">opts</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">servers</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="c1">-- Ensure mason installs the server</span>
</span></span><span class="line"><span class="cl">          <span class="n">rnix</span> <span class="o">=</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="n">settings</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="n">rnix</span> <span class="o">=</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;jose-elias-alvarez/null-ls.nvim&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">opts</span> <span class="o">=</span> <span class="kr">function</span><span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="kd">local</span> <span class="n">nls</span> <span class="o">=</span> <span class="n">require</span><span class="p">(</span><span class="s2">&#34;null-ls&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="kr">if</span> <span class="n">type</span><span class="p">(</span><span class="n">opts.sources</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&#34;table&#34;</span> <span class="kr">then</span>
</span></span><span class="line"><span class="cl">          <span class="n">vim.list_extend</span><span class="p">(</span><span class="n">opts.sources</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="n">nls.builtins</span><span class="p">.</span><span class="n">code_actions.statix</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="n">nls.builtins</span><span class="p">.</span><span class="n">formatting.alejandra</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="n">nls.builtins</span><span class="p">.</span><span class="n">diagnostics.deadnix</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="p">})</span>
</span></span><span class="line"><span class="cl">      <span class="kr">end</span>
</span></span><span class="line"><span class="cl">    <span class="kr">end</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This config will make sure we have some basic LSP i.e. missing <code>pkgs</code> definition in our expressions. It will
auto-format our code as well. Which is very helpful.</p>
<blockquote>
<p>P.S. I still don&rsquo;t have any form of auto-complete setup. If you have any ideas I&rsquo;m all ears.</p>
</blockquote>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/dotfiles/-/blob/618ea7283587c19b76e860a7a7fd20c0c1ba53e2/home-manager/editors/nvim/config/lua/plugins/nix.lua">My nix.lua</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix VIA Permission Issues on Linux</title>
      <link>https://haseebmajid.dev/posts/2023-08-02-til-how-to-fix-via-permission-issues-on-linux/</link>
      <pubDate>Wed, 02 Aug 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-08-02-til-how-to-fix-via-permission-issues-on-linux/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix VIA Permission Issues on Linux&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I have been trying to configure my newish Keychron keyboard using &lt;a href=&#34;https://www.caniusevia.com/&#34;&gt;VIA&lt;/a&gt;.
To add a key to be able to take print screens, making use of the layers provided,
as my Keychron Q1 PRO doesn&amp;rsquo;t have a dedicated print key &amp;#x1f613;.&lt;/p&gt;
&lt;p&gt;However, when I opened the app or the &lt;a href=&#34;https://usevia.app/&#34;&gt;website&lt;/a&gt;, I would get
the following error.&lt;/p&gt;
&lt;p&gt;If we go to &lt;code&gt;chrome://device-log&lt;/code&gt; you should be able to see something like this:
&lt;code&gt;Failed to open &#39;/dev/hidraw9&#39;: FILE_ERROR_ACCESS_DENIED&lt;/code&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix VIA Permission Issues on Linux</strong></p>
<p>Recently I have been trying to configure my newish Keychron keyboard using <a href="https://www.caniusevia.com/">VIA</a>.
To add a key to be able to take print screens, making use of the layers provided,
as my Keychron Q1 PRO doesn&rsquo;t have a dedicated print key &#x1f613;.</p>
<p>However, when I opened the app or the <a href="https://usevia.app/">website</a>, I would get
the following error.</p>
<p>If we go to <code>chrome://device-log</code> you should be able to see something like this:
<code>Failed to open '/dev/hidraw9': FILE_ERROR_ACCESS_DENIED</code>.</p>
<p><img
        loading="lazy"
        src="/posts/2023-08-02-til-how-to-fix-via-permission-issues-on-linux/images/error.png"
        type=""
        alt="Error"
        
      /></p>
<blockquote>
<p>hidraw enables raw access to USB and Bluetooth Human Interface (hidraw) devices.</p>
</blockquote>
<p>This means Chrome cannot access our keyboard, so to fix this we can do something like:</p>
<pre tabindex="0"><code>sudo chmod a+rw /dev/hidraw9
</code></pre><p>Then open the app/go to the website and you should see the errors are gone.</p>
<p><img
        loading="lazy"
        src="/posts/2023-08-02-til-how-to-fix-via-permission-issues-on-linux/images/loaded.png"
        type=""
        alt="Loaded"
        
      /></p>
<p>To set the original permissions you can do:</p>
<pre tabindex="0"><code>sudo chmod 600 /dev/hidraw8
</code></pre><h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://bbs.archlinux.org/viewtopic.php?id=285709">Arch Forum Post which helped me</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to get Kanshi to work on NixOS and Hyprland</title>
      <link>https://haseebmajid.dev/posts/2023-07-25-nixos-kanshi-and-hyprland/</link>
      <pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-07-25-nixos-kanshi-and-hyprland/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to get Kanshi to work on NixOS and Hyprland&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have been using Kanshi to setup my monitor setups automagically depending on which monitors are plugged
i.e. if my laptop is docked or not. If it is docked I want my laptop display to be off, when not docked I want
it to be on. So my kanshi config file &lt;code&gt;~/.config/kanshi/config&lt;/code&gt; to look something like:&lt;/p&gt;
&lt;p&gt;I use the name of my monitors as the ports they are plugged into my vary.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to get Kanshi to work on NixOS and Hyprland</strong></p>
<p>I have been using Kanshi to setup my monitor setups automagically depending on which monitors are plugged
i.e. if my laptop is docked or not. If it is docked I want my laptop display to be off, when not docked I want
it to be on. So my kanshi config file <code>~/.config/kanshi/config</code> to look something like:</p>
<p>I use the name of my monitors as the ports they are plugged into my vary.</p>
<pre tabindex="0"><code>profile home_office {
  output &#34;GIGA-BYTE TECHNOLOGY CO., LTD. Gigabyte M32U 21351B000087&#34; mode 3840x2160@60Hz position 3840,0
  output &#34;Dell Inc. DELL G3223Q 82X70P3&#34; mode 3840x2160@60Hz position 0,0
  output &#34;eDP-1&#34; disable
}

profile undocked {
  output &#34;eDP-1&#34; enable scale 1.100000
}
</code></pre><p>To set this up using NixOS/home-manager we can do something like this say a file called <code>kanshi.nix</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">services</span><span class="o">.</span><span class="n">kanshi</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">systemdTarget</span> <span class="o">=</span> <span class="s2">&#34;hyprland-session.target&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">profiles</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">undocked</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">outputs</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">criteria</span> <span class="o">=</span> <span class="s2">&#34;eDP-1&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">scale</span> <span class="o">=</span> <span class="mi">1</span><span class="mf">.1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">status</span> <span class="o">=</span> <span class="s2">&#34;enable&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">];</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="n">home_office</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">outputs</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">criteria</span> <span class="o">=</span> <span class="s2">&#34;GIGA-BYTE TECHNOLOGY CO., LTD. Gigabyte M32U 21351B000087&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">position</span> <span class="o">=</span> <span class="s2">&#34;3840,0&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">mode</span> <span class="o">=</span> <span class="s2">&#34;3840x2160@60Hz&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">criteria</span> <span class="o">=</span> <span class="s2">&#34;Dell Inc. DELL G3223Q 82X70P3&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">position</span> <span class="o">=</span> <span class="s2">&#34;0,0&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">mode</span> <span class="o">=</span> <span class="s2">&#34;3840x2160@60Hz&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">criteria</span> <span class="o">=</span> <span class="s2">&#34;eDP-1&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">status</span> <span class="o">=</span> <span class="s2">&#34;disable&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">];</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>I was unable to get it work until I added this line <code>systemdTarget = &quot;hyprland-session.target&quot;;</code>, this is the
Systemd target to bind to. Since we are using hyprland we need to attach to hyprland the default is sway.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to use NUR with Home-Manager &amp; Nix Flakes</title>
      <link>https://haseebmajid.dev/posts/2023-06-22-til-use-nur-with-home-manager-flake/</link>
      <pubDate>Thu, 22 Jun 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-06-22-til-use-nur-with-home-manager-flake/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to use NUR with Home-Manager &amp;amp; Nix Flakes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;NUR is the Nix user repository like the Arch user repository (AUR). It exists so that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The NUR was created to share new packages from the community in a faster and more decentralized way. - &lt;a href=&#34;https://github.com/nix-community/NUR&#34;&gt;https://github.com/nix-community/NUR&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If we want to install packages from NUR in our home manager config which is set up using Nix Flakes.
Assuming you build your home manager like&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to use NUR with Home-Manager &amp; Nix Flakes</strong></p>
<p>NUR is the Nix user repository like the Arch user repository (AUR). It exists so that:</p>
<blockquote>
<p>The NUR was created to share new packages from the community in a faster and more decentralized way. - <a href="https://github.com/nix-community/NUR">https://github.com/nix-community/NUR</a></p>
</blockquote>
<p>If we want to install packages from NUR in our home manager config which is set up using Nix Flakes.
Assuming you build your home manager like</p>
<p>To do so first add it as an input in our <code>flake.nix</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl">  <span class="n">inputs</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">nixpkgs</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;github:nixos/nixpkgs/nixos-unstable&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">nur</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;github:nix-community/NUR&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span></code></pre></div><p>Then we can use with home-manager by importing <code>inputs.nur.hmModules.nur</code>, for example in your <code>home.nix</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl">  <span class="n">imports</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="n">inputs</span><span class="o">.</span><span class="n">nur</span><span class="o">.</span><span class="n">hmModules</span><span class="o">.</span><span class="n">nur</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span></code></pre></div><p>Then we should be able to import packages like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl">  <span class="n">home</span><span class="o">.</span><span class="n">packages</span> <span class="o">=</span> <span class="k">with</span> <span class="n">pkgs</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="n">nur</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">peel</span><span class="o">.</span><span class="n">rofi-wifi-menu</span>
</span></span><span class="line"><span class="cl">    <span class="n">nur</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">peel</span><span class="o">.</span><span class="n">rofi-emoji</span>
</span></span><span class="line"><span class="cl">  <span class="p">];</span>
</span></span></code></pre></div><blockquote>
<p>Note these packages won&rsquo;t work because they are out of date, and they caused me a lot of grief 😅, thinking it wasn&rsquo;t working.</p>
</blockquote>
<p>But that&rsquo;s it! You should be able to use NUR packages with home-manager setup via a flake.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Declaratively Setup Mullvad VPN with NixOS</title>
      <link>https://haseebmajid.dev/posts/2023-06-20-til-how-to-declaratively-setup-mullvad-with-nixos/</link>
      <pubDate>Tue, 20 Jun 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-06-20-til-how-to-declaratively-setup-mullvad-with-nixos/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Declaratively Setup Mullvad VPN with NixOS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have recently moved to NixOS, one of the great features of NixOS is that you can set up your entire machine
from a single git repo. We can do this declaratively, what we mean by this is we tell nix what we want the state to
be and nixos will work out how to get there.&lt;/p&gt;
&lt;p&gt;For example, we can install Mullvad set various options already. This means on a new machine we don&amp;rsquo;t manually have to
setup these mullvad settings.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Declaratively Setup Mullvad VPN with NixOS</strong></p>
<p>I have recently moved to NixOS, one of the great features of NixOS is that you can set up your entire machine
from a single git repo. We can do this declaratively, what we mean by this is we tell nix what we want the state to
be and nixos will work out how to get there.</p>
<p>For example, we can install Mullvad set various options already. This means on a new machine we don&rsquo;t manually have to
setup these mullvad settings.</p>
<p>We can set it up by doing something like <code>mullvad.nix</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span><span class="n">pkgs</span><span class="o">,</span> <span class="n">config</span><span class="o">,</span> <span class="o">...</span><span class="p">}:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">environment</span><span class="o">.</span><span class="n">systemPackages</span> <span class="o">=</span> <span class="p">[</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">mullvad-vpn</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">mullvad</span> <span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="n">services</span><span class="o">.</span><span class="n">mullvad-vpn</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">systemd</span><span class="o">.</span><span class="n">services</span><span class="o">.</span><span class="s2">&#34;mullvad-daemon&#34;</span><span class="o">.</span><span class="n">postStart</span> <span class="o">=</span> <span class="k">let</span>
</span></span><span class="line"><span class="cl">    <span class="n">mullvad</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">services</span><span class="o">.</span><span class="n">mullvad-vpn</span><span class="o">.</span><span class="n">package</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">in</span> <span class="s1">&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">    while ! </span><span class="si">${</span><span class="n">mullvad</span><span class="si">}</span><span class="s1">/bin/mullvad status &gt;/dev/null; do sleep 1; done
</span></span></span><span class="line"><span class="cl"><span class="s1">    </span><span class="si">${</span><span class="n">mullvad</span><span class="si">}</span><span class="s1">/bin/mullvad auto-connect set on
</span></span></span><span class="line"><span class="cl"><span class="s1">    </span><span class="si">${</span><span class="n">mullvad</span><span class="si">}</span><span class="s1">/bin/mullvad tunnel ipv6 set on
</span></span></span><span class="line"><span class="cl"><span class="s1">    </span><span class="si">${</span><span class="n">mullvad</span><span class="si">}</span><span class="s1">/bin/mullvad set default \
</span></span></span><span class="line"><span class="cl"><span class="s1">        --block-ads --block-trackers --block-malware
</span></span></span><span class="line"><span class="cl"><span class="s1">  &#39;&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The main part here is we set up mullvad and then in the service we set various options. That can be set via the
GUI app.</p>
<pre tabindex="0"><code>${mullvad}/bin/mullvad set default \
        --block-ads --block-trackers --block-malware
</code></pre><p>One improvement we could make is to use a secret manager like <code>nix-sops</code> and even login automatically using our account id [1].</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/dotfiles/-/blob/6f2bac80e57999c793eb8ae48ca1dfc8dafa8f9e/hosts/common/optional/mullvad.nix">Dotfiles</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Add Vim Navigation FZF</title>
      <link>https://haseebmajid.dev/posts/2023-05-30-til-how-to-vim-navigation-to-fzf/</link>
      <pubDate>Tue, 30 May 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-05-30-til-how-to-vim-navigation-to-fzf/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Add Vim Navigation FZF&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/junegunn/fzf&#34;&gt;FZF&lt;/a&gt; is an amazing fuzzy finder tool, that is super flexible and you can create some
cool cli one-liners with it. For example, I use it with the fish shell plugin to search through my command history (CTRL + R).&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2023-05-30-til-how-to-vim-navigation-to-fzf/images/fzf.jpg&#34;
        type=&#34;&#34;
        alt=&#34;FZF Example&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;In this post, I will show you how vim style navigation to the FZF pop-up preview. All we need to do is add the following to the
relevant file i.e. &lt;code&gt;fish.config&lt;/code&gt;, &lt;code&gt;.bashrc&lt;/code&gt; or &lt;code&gt;.zshrc&lt;/code&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Add Vim Navigation FZF</strong></p>
<p><a href="https://github.com/junegunn/fzf">FZF</a> is an amazing fuzzy finder tool, that is super flexible and you can create some
cool cli one-liners with it. For example, I use it with the fish shell plugin to search through my command history (CTRL + R).</p>
<p><img
        loading="lazy"
        src="/posts/2023-05-30-til-how-to-vim-navigation-to-fzf/images/fzf.jpg"
        type=""
        alt="FZF Example"
        
      /></p>
<p>In this post, I will show you how vim style navigation to the FZF pop-up preview. All we need to do is add the following to the
relevant file i.e. <code>fish.config</code>, <code>.bashrc</code> or <code>.zshrc</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">FZF_DEFAULT_OPTS</span><span class="o">=</span><span class="s2">&#34;--bind &#39;j:down,k:up,ctrl-j:preview-down,ctrl-k:preview-up&#39;&#34;</span>
</span></span></code></pre></div><p>This will mean we can move and up down using the normal Vim binding <code>j</code> and <code>k</code></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to change the fish greeter</title>
      <link>https://haseebmajid.dev/posts/2023-05-25-til-how-to-change-fish-greeter/</link>
      <pubDate>Thu, 25 May 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-05-25-til-how-to-change-fish-greeter/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to change the fish greeter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this post I will show you how you can change your fish shell greeter from the default&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Welcome to fish, the friendly interactive shell
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Type &lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; instructions on how to use fish
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To something custom, this will run every time you open a new shell!&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2023-05-25-til-how-to-change-fish-greeter/images/greeting.png&#34;
        type=&#34;&#34;
        alt=&#34;Fish Greeting&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;To do this, go to your &lt;code&gt;fish_greeter.fish&lt;/code&gt; file which can usually be found at &lt;code&gt;~/.config/fish/functions/fish_greeting.fish&lt;/code&gt;.
Where mine looks like:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to change the fish greeter</strong></p>
<p>In this post I will show you how you can change your fish shell greeter from the default</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Welcome to fish, the friendly interactive shell
</span></span><span class="line"><span class="cl">Type <span class="sb">`</span><span class="nb">help</span><span class="sb">`</span> <span class="k">for</span> instructions on how to use fish
</span></span></code></pre></div><p>To something custom, this will run every time you open a new shell!</p>
<p><img
        loading="lazy"
        src="/posts/2023-05-25-til-how-to-change-fish-greeter/images/greeting.png"
        type=""
        alt="Fish Greeting"
        
      /></p>
<p>To do this, go to your <code>fish_greeter.fish</code> file which can usually be found at <code>~/.config/fish/functions/fish_greeting.fish</code>.
Where mine looks like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fish" data-lang="fish"><span class="line"><span class="cl"><span class="k">function</span> <span class="nb">fish_greeting
</span></span></span><span class="line"><span class="cl"><span class="nb">    </span><span class="nf">fortune</span> <span class="o">|</span> <span class="nf">lolcat</span> <span class="na">-f</span> <span class="o">|</span> <span class="nf">chara</span> say <span class="na">-c</span> kitten
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>fortune generates a random quote, then lolcat colours that quote as a rainbow and finally chara prints out the kitten.</p>
<h2 id="nix-optional">Nix (Optional)</h2>
<p>If you are using fish to configure your fish shell you can do something like (I do this in a file called <code>fish.nix</code>):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="p">{</span> <span class="n">lib</span><span class="o">,</span> <span class="n">pkgs</span><span class="o">,</span> <span class="o">...</span> <span class="p">}:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">programs</span><span class="o">.</span><span class="n">fish</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">enable</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">functions</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">fish_greeting</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">description</span> <span class="o">=</span> <span class="s2">&#34;Greeting to show when starting a fish shell&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">body</span> <span class="o">=</span> <span class="s2">&#34;fortune | lolcat -f | chara say -c kitten&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Get VSCode ESLint to Sort Imports</title>
      <link>https://haseebmajid.dev/posts/2023-04-09--til-how-to-get-vscode-eslint-to-sort-imports-/</link>
      <pubDate>Sun, 09 Apr 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-04-09--til-how-to-get-vscode-eslint-to-sort-imports-/</guid>
      <description>&lt;p&gt;I use VS Code as my text editor, one of the features I really like about VS Code is that it will format our file on save.
Which saves needing to run a CLI tool to do it. For example, running &lt;code&gt;prettier&lt;/code&gt;. As part of the formatting on save you can
set an option to organise your imports as well.&lt;/p&gt;
&lt;p&gt;If you open your &lt;code&gt;settings.json&lt;/code&gt;, you can add a section like this:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I use VS Code as my text editor, one of the features I really like about VS Code is that it will format our file on save.
Which saves needing to run a CLI tool to do it. For example, running <code>prettier</code>. As part of the formatting on save you can
set an option to organise your imports as well.</p>
<p>If you open your <code>settings.json</code>, you can add a section like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;eslint.validate&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;javascript&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;svelte&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;javascriptreact&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;typescript&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;typescriptreact&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;[typescript]&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;editor.defaultFormatter&#34;</span><span class="p">:</span> <span class="s2">&#34;esbenp.prettier-vscode&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;editor.tabSize&#34;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;editor.codeActionsOnSave&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;source.organizeImports&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;source.fixAll&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Now this format our typescript files automatically when we save it, including organising our imports.
Now this is all well and good, except when we add the following ESLint plugin
<a href="https://github.com/import-js/ESLint-plugin-import"><code>ESLint-plugin-import</code></a>.</p>
<p>This plugin lets us set our own rules for how to sort plugins and how to organise them into groups.
So our ESLint config may look something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">  <span class="kr">extends</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">    <span class="s2">&#34;plugin:import/errors&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;plugin:import/warnings&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;plugin:import/typescript&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">rules</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">    <span class="s2">&#34;import/order&#34;</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;warn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">groups</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;builtin&#34;</span><span class="p">,</span> <span class="s2">&#34;external&#34;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&#34;sibling&#34;</span><span class="p">,</span> <span class="s2">&#34;parent&#34;</span><span class="p">],</span> <span class="s2">&#34;index&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nx">pathGroups</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nx">pattern</span><span class="o">:</span> <span class="s2">&#34;$app/**&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="nx">group</span><span class="o">:</span> <span class="s2">&#34;external&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="p">},</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nx">pattern</span><span class="o">:</span> <span class="s2">&#34;~/**&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="nx">group</span><span class="o">:</span> <span class="s2">&#34;sibling&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nx">alphabetize</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">order</span><span class="o">:</span> <span class="s2">&#34;asc&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">caseInsensitive</span><span class="o">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;newlines-between&#34;</span><span class="o">:</span> <span class="s2">&#34;always&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>Now this will conflict with the way VS Code will format our imports, it will format them incorrectly according to the settings we have
just set up in our ESLint config. To stop this from happening it&rsquo;s very simple we need to remove the <code>&quot;source.organizeImports&quot;: true,</code>
line from our config. Now VS Code will use just ESLint to format our imports 🎉.</p>
<p>There is one downside to this approach I have noticed, which is unused imports no longer get removed automatically, which used to happen.
But this will get fixed by pre-commit hooks.</p>
<details
  class="notice info"
  open="true"
>
    <summary class="notice-title">Remove Unused Imports</summary>
  
  EDIT: I found this option which will hopefully fix the above issue <code>&quot;source.removeUnusedImports&quot;: true</code>
</details>

<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/bookmarkey/gui/-/blob/7ce4d9326b610ae16840691d16fbb82a6ec4f5ee/.ESLintrc.cjs">Example Repo</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Deploy &#39;Multiple&#39; Sites on One GitLab Page Site</title>
      <link>https://haseebmajid.dev/posts/2023-04-06-til-how-to-deploy-multiple-sites-on-one-gitlab-page-site/</link>
      <pubDate>Thu, 06 Apr 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-04-06-til-how-to-deploy-multiple-sites-on-one-gitlab-page-site/</guid>
      <description>&lt;p&gt;I have a repo which I use to store all of my conference and similar talks. This repo includes any code examples
and most importantly the slides.&lt;/p&gt;
&lt;p&gt;At the moment all the slides are RevealJS &amp;ldquo;sites&amp;rdquo;, which means it&amp;rsquo;s a presentation built in HTML. Now I would like
to have all my talks deployed to single GitLab pages site. For example something like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://hmajid2301.io/talks/an-intro-to-pocketbase/&#34;&gt;https://hmajid2301.io/talks/an-intro-to-pocketbase/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hmajid2301.io/talks/docker-as-a-dev-tool/&#34;&gt;https://hmajid2301.io/talks/docker-as-a-dev-tool/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So how can we do this ? Simple! In our job to deploy the site we just need to add &lt;code&gt;public/docker-as-a-dev-tool&lt;/code&gt; and &lt;code&gt;public/an-intro-to-pocketbase&lt;/code&gt;
respectively. Which ever path we provide is that path we will be able to access those slides on.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I have a repo which I use to store all of my conference and similar talks. This repo includes any code examples
and most importantly the slides.</p>
<p>At the moment all the slides are RevealJS &ldquo;sites&rdquo;, which means it&rsquo;s a presentation built in HTML. Now I would like
to have all my talks deployed to single GitLab pages site. For example something like:</p>
<ul>
<li><a href="https://hmajid2301.io/talks/an-intro-to-pocketbase/">https://hmajid2301.io/talks/an-intro-to-pocketbase/</a></li>
<li><a href="https://hmajid2301.io/talks/docker-as-a-dev-tool/">https://hmajid2301.io/talks/docker-as-a-dev-tool/</a></li>
</ul>
<p>So how can we do this ? Simple! In our job to deploy the site we just need to add <code>public/docker-as-a-dev-tool</code> and <code>public/an-intro-to-pocketbase</code>
respectively. Which ever path we provide is that path we will be able to access those slides on.</p>
<p>Here is an example <code>.gitlab-ci.yml</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="c"># .gitlab-ci.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">stages</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">pages</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="nt">pages</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">pages</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">only</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">scripts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">mkdir -p public/docker-as-a-dev-tool</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">mv docker-as-a-dev-tool public/docker-as-a-dev-tool</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">artifacts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">paths</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">public</span><span class="w">
</span></span></span></code></pre></div><p>Voila that&rsquo;s it! Now we have multiple slides deployed to the same GitLab pages site.
So I can keep all of my talks nice and neat in a single repo.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/talks">My Talks Project</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Mock Classes Using Vitest</title>
      <link>https://haseebmajid.dev/posts/2023-04-01--til-mock-classes-using-vitest-/</link>
      <pubDate>Sat, 01 Apr 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-04-01--til-mock-classes-using-vitest-/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Mock Classes Using Vitest&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I have been creating a SvelteKit app, when creating a new SvelteKit app you get a choice
of different things you can add. Such as using &lt;code&gt;vitest&lt;/code&gt; for unit testing.&lt;/p&gt;
&lt;p&gt;I needed to spy on/mock a method in a class, to see if it was called when a button was pressed and, it was called
with the correct arguments.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say we have a &lt;code&gt;Button&lt;/code&gt; component which looks like this:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Mock Classes Using Vitest</strong></p>
<p>Recently I have been creating a SvelteKit app, when creating a new SvelteKit app you get a choice
of different things you can add. Such as using <code>vitest</code> for unit testing.</p>
<p>I needed to spy on/mock a method in a class, to see if it was called when a button was pressed and, it was called
with the correct arguments.</p>
<p>Let&rsquo;s say we have a <code>Button</code> component which looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-svelte" data-lang="svelte"><span class="line"><span class="cl"><span class="c">&lt;!-- button.svelte --&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="kr">import</span> <span class="p">{</span> <span class="nx">API</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;./api&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">api</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">API</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span> <span class="na">on:click</span><span class="o">=</span><span class="p">{</span><span class="nx">api</span><span class="p">.</span><span class="nx">create</span><span class="p">}</span><span class="err">&gt;</span><span class="s">Press</span> <span class="na">Me</span><span class="err">!&lt;/</span><span class="na">button</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Then the <code>api.ts</code> looks something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">API</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kr">async</span> <span class="nx">create() {</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// ... does something
</span></span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>So how do we test that the <code>create</code> method is called?
Let&rsquo;s assume we will be using the <code>svelte testing library</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="c1">// __tests__/button.test.ts
</span></span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">render</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;@testing-library/svelte&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">userEvent</span> <span class="kr">from</span> <span class="s2">&#34;@testing-library/user-event&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">describe</span><span class="p">,</span> <span class="nx">expect</span><span class="p">,</span> <span class="nx">test</span><span class="p">,</span> <span class="nx">vi</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;vitest&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Button</span> <span class="kr">from</span> <span class="s2">&#34;../Button.svelte&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">API</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;./api&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">describe</span><span class="p">(</span><span class="s2">&#34;Button&#34;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nx">test</span><span class="p">(</span><span class="s2">&#34;Successfully render Button&#34;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="nx">user</span> <span class="o">=</span> <span class="nx">userEvent</span><span class="p">.</span><span class="nx">setup</span><span class="p">();</span>
</span></span><span class="line hl"><span class="cl">		<span class="kr">const</span> <span class="nx">mock</span> <span class="o">=</span> <span class="nx">vi</span><span class="p">.</span><span class="nx">spyOn</span><span class="p">(</span><span class="nx">API</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="s2">&#34;create&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="p">{</span> <span class="nx">getByRole</span><span class="p">,</span> <span class="nx">getByLabelText</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">render</span><span class="p">(</span><span class="nx">Button</span><span class="p">,</span> <span class="p">{</span> <span class="nx">props</span><span class="o">:</span> <span class="p">{}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="nx">button</span> <span class="o">=</span> <span class="nx">getByRole</span><span class="p">(</span><span class="s2">&#34;button&#34;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;Add Bookmark&#34;</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">user</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">button</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="nx">expect</span><span class="p">(</span><span class="nx">mock</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">	<span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The key being this line <code>vi.spyOn(API.prototype, &quot;create&quot;)</code>, where we need to use <code>.prototype</code>.
So we can access the methods in the class. Without the <code>.prototype</code> we will not find the method
on the object itself.</p>
<p>That&rsquo;s it! Thanks for reading.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/bookmarkey/gui/-/blob/main/src/lib/components/organisms/__tests__/AddBookmarkModal.test.ts#L11">Example Test from my App</a></li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://testing-library.com/docs/svelte-testing-library/intro/">https://testing-library.com/docs/svelte-testing-library/intro/</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Use Multiple Auth Files in Playwright</title>
      <link>https://haseebmajid.dev/posts/2023-03-22--til-how-to-use-multiple-auth-in-playwright-/</link>
      <pubDate>Wed, 22 Mar 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-03-22--til-how-to-use-multiple-auth-in-playwright-/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Load Authenticate State in Playwright&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this post, I will quickly show you how you can reduce boilerplate code to log in to your app in Playwright tests.
Log in to our app is a very common action that will likely be required in most of our tests.&lt;/p&gt;
&lt;p&gt;You can read this &lt;a href=&#34;https://playwright.dev/docs/auth&#34;&gt;documentation here&lt;/a&gt;, which will explain how you can set this up.
However, what do you do if you want to say test the login flow or the register flow? You cannot use the same auth
file as all the other tests as you will already be logged in.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Load Authenticate State in Playwright</strong></p>
<p>In this post, I will quickly show you how you can reduce boilerplate code to log in to your app in Playwright tests.
Log in to our app is a very common action that will likely be required in most of our tests.</p>
<p>You can read this <a href="https://playwright.dev/docs/auth">documentation here</a>, which will explain how you can set this up.
However, what do you do if you want to say test the login flow or the register flow? You cannot use the same auth
file as all the other tests as you will already be logged in.</p>
<p>It is a great way to reduce boilerplate code from our tests, which would require us to write code to log in before each test.
You could log yourself in the test but, then we are adding more boilerplate code again.</p>
<p>What you can do is create a 2nd file say called <code>playwright/.auth/not_logged_in.json</code> which looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&#34;cookies&#34;</span><span class="p">:</span> <span class="p">[],</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&#34;origins&#34;</span><span class="p">:</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>In other words there is no state, so the user will not be logged in.
Then we can do something like this in say our <code>login.test.ts</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">import</span> <span class="kr">type</span> <span class="p">{</span> <span class="nx">Page</span><span class="p">,</span> <span class="nx">expect</span><span class="p">,</span> <span class="nx">test</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;@playwright/test&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">test</span><span class="p">.</span><span class="nx">describe</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kd">let</span> <span class="nx">page</span>: <span class="kt">Page</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line hl"><span class="cl">	<span class="nx">test</span><span class="p">.</span><span class="nx">beforeEach</span><span class="p">(</span><span class="kr">async</span> <span class="p">({</span> <span class="nx">browser</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="nx">loginContext</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">browser</span><span class="p">.</span><span class="nx">newContext</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">			<span class="nx">storageState</span><span class="o">:</span> <span class="s2">&#34;playwright/.auth/not_logged_in.json&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="p">});</span>
</span></span><span class="line"><span class="cl">		<span class="nx">page</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">loginContext</span><span class="p">.</span><span class="nx">newPage</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">	<span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nx">test</span><span class="p">(</span><span class="s2">&#34;Successfully login to app&#34;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">({</span> <span class="nx">baseURL</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="kr">goto</span><span class="p">(</span><span class="s2">&#34;/login&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="nx">email</span> <span class="o">=</span> <span class="s2">&#34;test@bookmarkey.app&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">locator</span><span class="p">(</span><span class="s1">&#39;[name=&#34;email&#34;]&#39;</span><span class="p">).</span><span class="kr">type</span><span class="p">(</span><span class="nx">email</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="nx">password</span> <span class="o">=</span> <span class="s2">&#34;password@11&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">locator</span><span class="p">(</span><span class="s1">&#39;[name=&#34;password&#34;]&#39;</span><span class="p">).</span><span class="kr">type</span><span class="p">(</span><span class="nx">password</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">locator</span><span class="p">(</span><span class="s1">&#39;button[type=&#34;submit&#34;]&#39;</span><span class="p">).</span><span class="nx">click</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">waitForURL</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">baseURL</span><span class="si">}</span><span class="sb">/my/collections/0`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nx">test</span><span class="p">(</span><span class="s2">&#34;Fail to login to app using incorrect credentials&#34;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">({</span> <span class="nx">baseURL</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="kr">goto</span><span class="p">(</span><span class="s2">&#34;/login&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="nx">email</span> <span class="o">=</span> <span class="s2">&#34;test@bookmarkey.app&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">locator</span><span class="p">(</span><span class="s1">&#39;[name=&#34;email&#34;]&#39;</span><span class="p">).</span><span class="kr">type</span><span class="p">(</span><span class="nx">email</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="nx">password</span> <span class="o">=</span> <span class="s2">&#34;wrong_password&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">locator</span><span class="p">(</span><span class="s1">&#39;[name=&#34;password&#34;]&#39;</span><span class="p">).</span><span class="kr">type</span><span class="p">(</span><span class="nx">password</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">locator</span><span class="p">(</span><span class="s1">&#39;button[type=&#34;submit&#34;]&#39;</span><span class="p">).</span><span class="nx">click</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="kr">const</span> <span class="nx">toastMessage</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">locator</span><span class="p">(</span><span class="s2">&#34;.message&#34;</span><span class="p">).</span><span class="nx">innerText</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">		<span class="nx">expect</span><span class="p">(</span><span class="nx">toastMessage</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="s2">&#34;Wrong email and password combination.&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">waitForURL</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">baseURL</span><span class="si">}</span><span class="sb">/login`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Rather than using the &ldquo;normal&rdquo; page argument provided by Playwright, we will create our context.
Using this stateless file, will mean the user is not logged in.</p>
<p>If we still want a test to use to automatically logged in we can do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">test</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;@playwright/test&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">test</span><span class="p">.</span><span class="nx">describe</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nx">test</span><span class="p">(</span><span class="s2">&#34;Successfully load collections in side bar&#34;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">({</span> <span class="nx">page</span><span class="p">,</span> <span class="nx">baseURL</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="kr">goto</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">baseURL</span><span class="si">}</span><span class="sb">/my/collections/0`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">getByRole</span><span class="p">(</span><span class="s2">&#34;link&#34;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;folder closed test&#34;</span> <span class="p">}).</span><span class="nx">click</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">		<span class="k">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">waitForURL</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">baseURL</span><span class="si">}</span><span class="sb">/my/collections/46lfmlwhymhv6xl`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>That&rsquo;s it!</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/bookmarkey/gui/-/blob/55f7a6456da20a362c7b7ccf6069a9118acaa7f7/tests/auth.setup.ts">Used in the Bookmarkey Project</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Set a Relationship on Golang Pocketbase</title>
      <link>https://haseebmajid.dev/posts/2023-03-08--til-how-to-set-a-relationship-on-golang-pocketbase-/</link>
      <pubDate>Wed, 08 Mar 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-03-08--til-how-to-set-a-relationship-on-golang-pocketbase-/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Set a Relationship on Golang Pocketbase&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://pocketbase.io/&#34;&gt;Pocketbase&lt;/a&gt; is a backend as a service, it is very nice because it is written in Golang
it can compile down to a single binary. It also allows us to extend it using Golang and use it as a framework.
In my case, I needed some extra logic before adding data to the database so I decided to extend Pocketbase
and write some of my business logic.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Set a Relationship on Golang Pocketbase</strong></p>
<p><a href="https://pocketbase.io/">Pocketbase</a> is a backend as a service, it is very nice because it is written in Golang
it can compile down to a single binary. It also allows us to extend it using Golang and use it as a framework.
In my case, I needed some extra logic before adding data to the database so I decided to extend Pocketbase
and write some of my business logic.</p>
<p>Part of the code involved adding some entries to the Database including a relationship. However, I noticed that the relationship
looked different in the Pocketbase GUI as compared with the ones I created using the Pocketbase client in the SvelteKit part of my app.</p>
<p>The other relationships showed up a bit differently, they didn&rsquo;t include the id of the relationship (as a foreign key) but rather a field
on the other collection. In the example below the relationship field I am referencing is the <code>bookmark_metadata</code>. Which uses the <code>title</code> field.</p>
<p><img
        loading="lazy"
        src="/posts/2023-03-08--til-how-to-set-a-relationship-on-golang-pocketbase-/images/bookmark.png"
        type=""
        alt="Bookmark"
        
      /></p>
<p>Where the bookmark metadata may look like:</p>
<p><img
        loading="lazy"
        src="/posts/2023-03-08--til-how-to-set-a-relationship-on-golang-pocketbase-/images/bookmark_metadata.png"
        type=""
        alt="Bookmark Metadata"
        
      /></p>
<p>We can achieve this using the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-golang" data-lang="golang"><span class="line"><span class="cl"><span class="nx">bookmarkRecord</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">models</span><span class="p">.</span><span class="nf">NewRecord</span><span class="p">(</span><span class="nx">collection</span><span class="p">)</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="nx">bookmarkRecord</span><span class="p">.</span><span class="nf">Set</span><span class="p">(</span><span class="s">&#34;bookmark_metadata&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="nx">metadataRecord</span><span class="p">.</span><span class="nx">Id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">bookmarkRecord</span><span class="p">.</span><span class="nf">Set</span><span class="p">(</span><span class="s">&#34;favourite&#34;</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">bookmarkRecord</span><span class="p">.</span><span class="nf">Set</span><span class="p">(</span><span class="s">&#34;collection&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">collectionID</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">bookmarkRecord</span><span class="p">.</span><span class="nf">Set</span><span class="p">(</span><span class="s">&#34;custom_order&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">math</span><span class="p">.</span><span class="nx">MaxInt32</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>The key being that we set <code>bookmark_metadata</code> as a slice (array).
However, if we did:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-golang" data-lang="golang"><span class="line"><span class="cl"><span class="nx">bookmarkRecord</span><span class="p">.</span><span class="nf">Set</span><span class="p">(</span><span class="s">&#34;bookmark_metadata&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">metadataRecord</span><span class="p">.</span><span class="nx">Id</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>In the GUI the record would look like this:</p>
<p><img
        loading="lazy"
        src="/posts/2023-03-08--til-how-to-set-a-relationship-on-golang-pocketbase-/images/bookmark_id.png"
        type=""
        alt="Bookmark ID"
        
      /></p>
<p>Both options will work for setting up a relationship between two collections. I just wanted to show you how you can set it
so it shows up like relationship created via the JS SDK. You can read more about creating records with Golang
<a href="https://pocketbase.io/docs/record-methods/#create-new-record">here</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Run Parallel Jobs on Gitlab CI (Different Stages)</title>
      <link>https://haseebmajid.dev/posts/2023-03-03-til-how-to-run-parallel-jobs-on-gitlab-ci/</link>
      <pubDate>Fri, 03 Mar 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-03-03-til-how-to-run-parallel-jobs-on-gitlab-ci/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Run Parallel Jobs on Gitlab CI (Different Stages)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you are familiar with Gitlab CI you probably know that jobs in the same stages will run in parallel.
However you can also run jobs in different stages at the same time. Let&amp;rsquo;s see our &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;stages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;deploy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;stage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;task format&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;lint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;stage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;task lint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;deploy:preview&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;stage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;deploy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;only&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;merge_request&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;docker&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;task deploy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So for my use case when a user creates a merge request, I want to run some tests against the code,
such as linting and formatting. But also deploy my app to a preview environment. Whilst these jobs
belong to different stages.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Run Parallel Jobs on Gitlab CI (Different Stages)</strong></p>
<p>If you are familiar with Gitlab CI you probably know that jobs in the same stages will run in parallel.
However you can also run jobs in different stages at the same time. Let&rsquo;s see our <code>.gitlab-ci.yml</code> looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">stages</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">test</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">deploy</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="nt">format</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">test</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">script</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">task format</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="nt">lint</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">test</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">script</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">task lint</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="nt">deploy:preview</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">deploy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">only</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">merge_request</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">docker</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">script</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">task deploy</span><span class="w">
</span></span></span></code></pre></div><p>So for my use case when a user creates a merge request, I want to run some tests against the code,
such as linting and formatting. But also deploy my app to a preview environment. Whilst these jobs
belong to different stages.</p>
<p>The deploy job shouldn&rsquo;t really depend on the jobs in the <code>test</code> stage as we still want to deploy our
app regardless so we can test in the preview environment.</p>
<p>We can do that using <code>needs</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> keywords, so our <code>deploy:preview</code> job will now look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">deploy:preview</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">deploy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">only</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">merge_request</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">  </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">docker</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">script</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">task deploy</span><span class="w">
</span></span></span></code></pre></div><p>Now our job will run at the same time as the <code>test</code> stage jobs.
The <code>needs</code> keyword is used to run our job out of order.</p>
<blockquote>
<p>An empty array ([]), to set the job to start as soon as the pipeline is created. - Gitlab CI Docs</p>
</blockquote>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://docs.gitlab.com/ee/ci/yaml/#needs">https://docs.gitlab.com/ee/ci/yaml/#needs</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to fix `structuredClone` to work on Netlify SvelteKit Site</title>
      <link>https://haseebmajid.dev/posts/2023-01-23-til-how-to-fix-structuredclone-to-work-on-netlify-sveltekit-site/</link>
      <pubDate>Mon, 23 Jan 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-01-23-til-how-to-fix-structuredclone-to-work-on-netlify-sveltekit-site/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to fix &lt;code&gt;structuredClone&lt;/code&gt; to work on Netlify SvelteKit Site&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I was working on my SvelteKit site and added some code like so to my &lt;code&gt;hook.server.ts&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;authStore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isValid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;collection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;users&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;authRefresh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;structuredClone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pb&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;authStore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;failed to refresh auth&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;undefined&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;authStore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;clear&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I needed to add the &lt;code&gt;structuredClone&lt;/code&gt; function so that only POJO (plain old javascript objects) would get stored in the &lt;code&gt;event.locals.users&lt;/code&gt;
variable. However when I deployed this to production in Netlify. This broke my site! Specifically, it wouldn&amp;rsquo;t let the user log in.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to fix <code>structuredClone</code> to work on Netlify SvelteKit Site</strong></p>
<p>Recently I was working on my SvelteKit site and added some code like so to my <code>hook.server.ts</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">locals</span><span class="p">.</span><span class="nx">pb</span><span class="p">.</span><span class="nx">authStore</span><span class="p">.</span><span class="nx">isValid</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">await</span> <span class="nx">event</span><span class="p">.</span><span class="nx">locals</span><span class="p">.</span><span class="nx">pb</span><span class="p">.</span><span class="nx">collection</span><span class="p">(</span><span class="s2">&#34;users&#34;</span><span class="p">).</span><span class="nx">authRefresh</span><span class="p">();</span>
</span></span><span class="line hl"><span class="cl">        <span class="nx">event</span><span class="p">.</span><span class="nx">locals</span><span class="p">.</span><span class="nx">user</span> <span class="o">=</span> <span class="nx">structuredClone</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">locals</span><span class="p">.</span><span class="nx">pb</span><span class="o">?</span><span class="p">.</span><span class="nx">authStore</span><span class="p">.</span><span class="nx">model</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;failed to refresh auth&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">event</span><span class="p">.</span><span class="nx">locals</span><span class="p">.</span><span class="nx">user</span> <span class="o">=</span> <span class="kc">undefined</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="nx">event</span><span class="p">.</span><span class="nx">locals</span><span class="p">.</span><span class="nx">pb</span><span class="p">.</span><span class="nx">authStore</span><span class="p">.</span><span class="nx">clear</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>I needed to add the <code>structuredClone</code> function so that only POJO (plain old javascript objects) would get stored in the <code>event.locals.users</code>
variable. However when I deployed this to production in Netlify. This broke my site! Specifically, it wouldn&rsquo;t let the user log in.</p>
<p>If you deploy your SvelteKit app on Netlify the server-side code gets turned into functions for us automagically! I was able to work out
that <code>structuredClone</code> function broke my app because in my <code>login</code> function I could see something like:</p>
<pre tabindex="0"><code>ReferenceError: structuredClone is not defined
</code></pre><p><img
        loading="lazy"
        src="/posts/2023-01-23-til-how-to-fix-structuredclone-to-work-on-netlify-sveltekit-site/images/netlify_functions.png"
        type=""
        alt="Netlify Functions"
        
      /></p>
<p>It seems that the <code>structuredClone</code> was only added in nodejs 17 <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. However, Netlify functions default to nodejs 16.</p>
<blockquote>
<p>For all Node.js functions deployed on or after July 11, 2022, Netlify uses Node.js 16 as the default runtime. - <a href="https://docs.netlify.com/functions/optional-configuration/?fn-language=js">https://docs.netlify.com/functions/optional-configuration/?fn-language=js</a></p>
</blockquote>
<p>Reading the docs we can see if we set the <code>AWS_LAMBDA_JS_RUNTIME</code> in the GUI to <code>nodejs18.x</code> this will force our functions to use nodejs 18.</p>
<p><img
        loading="lazy"
        src="/posts/2023-01-23-til-how-to-fix-structuredclone-to-work-on-netlify-sveltekit-site/images/netlify_build_vars.png"
        type=""
        alt="Netlify Builds Vars"
        
      /></p>
<p>And that&rsquo;s it! By setting our nodejs version to 18, we will be able to use the <code>structuredClone</code> function.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://stackoverflow.com/a/73704608/3108619">https://stackoverflow.com/a/73704608/3108619</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Autofocus on Inputs in Svelte</title>
      <link>https://haseebmajid.dev/posts/2023-01-19-til-how-to-autofocus-on-inputs-in-svelte/</link>
      <pubDate>Thu, 19 Jan 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-01-19-til-how-to-autofocus-on-inputs-in-svelte/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Autofocus on Inputs in Svelte&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this post, I will show you how you can autofocus on input that is in a child component.
So in my use case, I want the user to click a button to add a &amp;ldquo;collection&amp;rdquo; and then it will show the input
and immediately focus on it. Which looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2023-01-19-til-how-to-autofocus-on-inputs-in-svelte/images/autofocus.gif&#34;
        type=&#34;&#34;
        alt=&#34;Autofocus Input&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;So how can we do this?&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Autofocus on Inputs in Svelte</strong></p>
<p>In this post, I will show you how you can autofocus on input that is in a child component.
So in my use case, I want the user to click a button to add a &ldquo;collection&rdquo; and then it will show the input
and immediately focus on it. Which looks something like this:</p>
<p><img
        loading="lazy"
        src="/posts/2023-01-19-til-how-to-autofocus-on-inputs-in-svelte/images/autofocus.gif"
        type=""
        alt="Autofocus Input"
        
      /></p>
<p>So how can we do this?</p>
<p>Let&rsquo;s say we have a child component called <code>Input.svelte</code> which looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-svelte" data-lang="svelte"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="kr">export</span> <span class="kd">let</span> <span class="kr">type</span><span class="o">:</span> <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="kr">export</span> <span class="kd">let</span> <span class="nx">name</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="kr">export</span> <span class="kd">let</span> <span class="nx">ref</span>: <span class="kt">HTMLInputElement</span> <span class="o">|</span> <span class="kc">undefined</span> <span class="o">=</span> <span class="kc">undefined</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">input</span> <span class="na">bind:this</span><span class="o">=</span><span class="p">{</span><span class="nx">ref</span><span class="p">}</span> <span class="p">{</span><span class="nx">name</span><span class="p">}</span> <span class="p">{</span><span class="kr">type</span><span class="p">}</span> <span class="s">/</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The key prop here is <code>ref</code>, which we will use to focus on our input.
<code>ref</code> is a reference to the component itself.
Then in our parent component say called <code>AddCollection.svelte</code> we can do something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-svelte" data-lang="svelte"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="kr">import</span> <span class="p">{</span> <span class="nx">tick</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;svelte&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">ref</span>: <span class="kt">HTMLInputElement</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">	<span class="na">on:click</span><span class="o">=</span><span class="p">{</span><span class="kr">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line hl"><span class="cl">		<span class="k">await</span> <span class="nx">tick</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">		<span class="nx">ref</span><span class="o">?</span><span class="p">.</span><span class="nx">focus</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">	<span class="p">}}</span><span class="err">&gt;</span>
</span></span><span class="line"><span class="cl">	Add Collection
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">Input</span> <span class="na">bind:ref</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text&#34;</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;addCollection&#34;</span> <span class="p">/&gt;</span>
</span></span></code></pre></div><details
  class="notice warning"
  open="true"
>
    <summary class="notice-title">Bind</summary>
  
  <p>In the parent component, we want to use <code>bind:ref</code>, as we don&rsquo;t want to bind to the <code>Input</code>
but pass the prop to the child and also bind our variable to it.</p>
<p>If we do <code>bind:this={ref}</code> in <code>AddCollection.svelte</code> this will not work as far as I know.</p>

</details>

<p>That&rsquo;s it!</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li>Revelant <a href="https://stackoverflow.com/questions/57354001/how-to-focus-on-input-field-loaded-from-component-in-svelte">SO Post</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How Includes, Extends work with TS Config (with SvelteKit)</title>
      <link>https://haseebmajid.dev/posts/2023-01-14-til-how-includes-extends-work-with-ts-config-with-sveltekit/</link>
      <pubDate>Sat, 14 Jan 2023 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2023-01-14-til-how-includes-extends-work-with-ts-config-with-sveltekit/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How Includes, Extends work with TS Config (with SvelteKit)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have recently been creating an app with SvelteKit and Typescript. I noticed all of a sudden Typescript and VS Code not playing
nice with each other. It wouldn&amp;rsquo;t show me the types of variables that I knew it was showing me before. So I started to investigate
and work out what was wrong. I was getting &lt;code&gt;locals&lt;/code&gt; with a type &lt;code&gt;any&lt;/code&gt;:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How Includes, Extends work with TS Config (with SvelteKit)</strong></p>
<p>I have recently been creating an app with SvelteKit and Typescript. I noticed all of a sudden Typescript and VS Code not playing
nice with each other. It wouldn&rsquo;t show me the types of variables that I knew it was showing me before. So I started to investigate
and work out what was wrong. I was getting <code>locals</code> with a type <code>any</code>:</p>
<p><img
        loading="lazy"
        src="/posts/2023-01-14-til-how-includes-extends-work-with-ts-config-with-sveltekit/images/errors.png"
        type=""
        alt="TS Errors"
        
      /></p>
<p>Even though <code>locals</code> has a defined type in my <code>app.d.ts</code></p>
<p>I used the documentation to create my SvelteKit app like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">declare</span> <span class="kr">namespace</span> <span class="nx">App</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kr">type</span> <span class="nx">PocketBase</span> <span class="o">=</span> <span class="kr">import</span><span class="p">(</span><span class="s2">&#34;pocketbase&#34;</span><span class="p">).</span><span class="k">default</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="kr">interface</span> <span class="nx">Locals</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nx">user?</span>: <span class="kt">import</span><span class="p">(</span><span class="s2">&#34;pocketbase&#34;</span><span class="p">).</span><span class="nx">Record</span> <span class="o">|</span> <span class="kr">import</span><span class="p">(</span><span class="s2">&#34;pocketbase&#34;</span><span class="p">).</span><span class="nx">Admin</span> <span class="o">|</span> <span class="kc">null</span> <span class="o">|</span> <span class="kc">undefined</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">		<span class="nx">pb?</span>: <span class="kt">PocketBase</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm create svelte@latest my-app
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> my-app
</span></span><span class="line"><span class="cl">npm install
</span></span><span class="line"><span class="cl">npm run dev
</span></span></code></pre></div><p>This gives us a <code>tsconfig.json</code> file that looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&#34;extends&#34;</span><span class="p">:</span> <span class="s2">&#34;./.svelte-kit/tsconfig.json&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&#34;compilerOptions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;strict&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;allowUnreachableCode&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;exactOptionalPropertyTypes&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noImplicitAny&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noImplicitOverride&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noImplicitReturns&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noImplicitThis&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noFallthroughCasesInSwitch&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noUncheckedIndexedAccess&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;types&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;vite-plugin-pwa/client&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>My <code>tsconfig.json</code> looked like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&#34;extends&#34;</span><span class="p">:</span> <span class="s2">&#34;./.svelte-kit/tsconfig.json&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&#34;compilerOptions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;strict&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;allowUnreachableCode&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;exactOptionalPropertyTypes&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noImplicitAny&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noImplicitOverride&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noImplicitReturns&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noImplicitThis&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noFallthroughCasesInSwitch&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;noUncheckedIndexedAccess&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&#34;types&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;vite-plugin-pwa/client&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">	<span class="p">},</span>
</span></span><span class="line hl"><span class="cl">	<span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;./setupTest.ts&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The line breaking my configuration was the last <code>include</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> it turns out it was overwriting the include within the <code>./.svelte-kit/tsconfig.json</code>.
That we were extending above. Which had defined its own include:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;ambient.d.ts&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;./types/**/$types.d.ts&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../vite.config.ts&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../src/**/*.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../src/**/*.ts&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../src/**/*.svelte&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../src/**/*.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../src/**/*.ts&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../src/**/*.svelte&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../tests/**/*.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../tests/**/*.ts&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../tests/**/*.svelte&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Turns out we were just replacing all these files above with just <code>./setupTest.ts</code>, hence it couldn&rsquo;t find the types that SvelteKit creates
for us <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> 🤦‍♂️.</p>
<p>We were of course now overwriting all these files with just the one we specified. Causing VS Code to throw errors and not type things that
had types. Removing this line <code>&quot;include&quot;: [&quot;./setupTest.ts&quot;]</code> fixed the issue more.
In my case, I just moved this file into my <code>tests</code> folder.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I was trying to setup this <a href="https://github.com/chaance/vitest-dom">library</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Relevant <a href="https://stackoverflow.com/a/55015988/3108619">SO post</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Setup Netlify, Gitlab And Sentry</title>
      <link>https://haseebmajid.dev/posts/2022-12-29-til-how-to-setup-netlify-gitlab-and-sentry/</link>
      <pubDate>Thu, 29 Dec 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-12-29-til-how-to-setup-netlify-gitlab-and-sentry/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Setup Netlify, Gitlab And Sentry&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I will show you in this post how you can integrate Gitlab, Netlify and Sentry. I may do a more
detailed post in the future.&lt;/p&gt;
&lt;h2 id=&#34;gitlab---sentry&#34;&gt;GitLab -&amp;gt; Sentry&lt;/h2&gt;
&lt;p&gt;To connect Gitlab and Sentry follow &lt;a href=&#34;https://docs.sentry.io/product/integrations/source-code-mgmt/gitlab/&#34;&gt;this guide&lt;/a&gt;.
Then add the repos you want to monitor in Sentry. In my case, it is the Bookmarkey GUI.&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2022-12-29-til-how-to-setup-netlify-gitlab-and-sentry/images/sentry_repository.png&#34;
        type=&#34;&#34;
        alt=&#34;Sentry Repo List&#34;
        
      /&gt;&lt;/p&gt;
&lt;h2 id=&#34;netlify---gitlab&#34;&gt;Netlify -&amp;gt; GitLab&lt;/h2&gt;
&lt;p&gt;This integration is pretty simple just go through the normal Netlify setup process to add a new site.
You can read more about that &lt;a href=&#34;../../posts/2022-12-03-my-workflow-to-create-a-new-post-using-hugo,-netlifycms,-netlify-and-gitlab-together&#34;&gt;here&lt;/a&gt;
and &lt;a href=&#34;https://docs.netlify.com/welcome/add-new-site/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Setup Netlify, Gitlab And Sentry</strong></p>
<p>I will show you in this post how you can integrate Gitlab, Netlify and Sentry. I may do a more
detailed post in the future.</p>
<h2 id="gitlab---sentry">GitLab -&gt; Sentry</h2>
<p>To connect Gitlab and Sentry follow <a href="https://docs.sentry.io/product/integrations/source-code-mgmt/gitlab/">this guide</a>.
Then add the repos you want to monitor in Sentry. In my case, it is the Bookmarkey GUI.</p>
<p><img
        loading="lazy"
        src="/posts/2022-12-29-til-how-to-setup-netlify-gitlab-and-sentry/images/sentry_repository.png"
        type=""
        alt="Sentry Repo List"
        
      /></p>
<h2 id="netlify---gitlab">Netlify -&gt; GitLab</h2>
<p>This integration is pretty simple just go through the normal Netlify setup process to add a new site.
You can read more about that <a href="/posts/2022-12-03-my-workflow-to-create-a-new-post-using-hugo,-netlifycms,-netlify-and-gitlab-together">here</a>
and <a href="https://docs.netlify.com/welcome/add-new-site/">here</a>.</p>
<h2 id="netlify---sentry">Netlify -&gt; Sentry</h2>
<p>Finally, how can we connect Netlify and Sentry?</p>
<p>First, why do we want to do this? It is so we can link specific releases with Netlify deploys.
Such as if it was a deploy preview or a deploy to production.</p>
<p><img
        loading="lazy"
        src="/posts/2022-12-29-til-how-to-setup-netlify-gitlab-and-sentry/images/sentry_releases.png"
        type=""
        alt="Sentry Releases"
        
      /></p>
<p>To do this we will be using the <code>sentry-netlify-build-plugin</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.
First, let&rsquo;s follow the guide in the <a href="https://github.com/getsentry/sentry-netlify-build-plugin#create-a-sentry-internal-integration">README</a>.</p>
<p>We can install this via the GUI in Netlify however I prefer to keep as much of
my config in code. So we will use a <code>netlify.toml</code> file. Append the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">plugins</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="nx">package</span> <span class="p">=</span> <span class="s2">&#34;@sentry/netlify-build-plugin&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">inputs</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">sentryOrg</span> <span class="p">=</span> <span class="s2">&#34;majiy&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">sentryProject</span> <span class="p">=</span> <span class="s2">&#34;bookmarkey&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">sentryRepository</span> <span class="p">=</span> <span class="s2">&#34;HaseebMajid Apps / Bookmarkey / gui&#34;</span>
</span></span></code></pre></div><p>Update the specific sentry-related variables to match your project.
Remember since <code>SENTRY_AUTH_TOKEN</code> is a secret variable, created when we set up the internal integration with Netlify,
you should add that to the Netlify GUI directly.</p>
<p><img
        loading="lazy"
        src="/posts/2022-12-29-til-how-to-setup-netlify-gitlab-and-sentry/images/netlify_env_vars.png"
        type=""
        alt="Netlify ENV VARs"
        
      /></p>
<details
  class="notice info"
  open="true"
>
    <summary class="notice-title">Netlify Build Env Vars</summary>
  
  All the other sentry variables were pre-populated. I only added <code>SENTRY_AUTH_TOKEN</code> via the Netlify GUI.
</details>

<details
  class="notice warning"
  open="true"
>
    <summary class="notice-title">Sentry Repository Name</summary>
  
  <p>Note the name of the repository is not the Git URL but rather
the name of the project shown in your Sentry integration (shown in the above photo).</p>
<p>You can find this name by going to <code>Settings &gt; Repositories</code>.
Then copy the name of the project i.e. <code>HaseebMajid Apps / Bookmarkey / gui</code>.
It is not the hyperlink (<code>gitlab.com/banter-bus/bookmarkey/gui</code>) [^2].</p>

</details>

<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://github.com/getsentry/sentry-netlify-build-plugin">https://github.com/getsentry/sentry-netlify-build-plugin</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How To Add Custom Syntax Highlighting Rules in VS Code</title>
      <link>https://haseebmajid.dev/posts/2022-12-27-til-how-to-add-custom-syntax-highlighting-rules-in-vs-code/</link>
      <pubDate>Tue, 27 Dec 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-12-27-til-how-to-add-custom-syntax-highlighting-rules-in-vs-code/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How To Add Custom Syntax Highlighting Rules in VS Code&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The other day (a few months ago) I was comparing Goland and VS Code for Golang development.
I noticed Goland by default seemed to have nicer syntax highlighting, so I started looking at
what I could do in VS Code to do this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Before&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2022-12-27-til-how-to-add-custom-syntax-highlighting-rules-in-vs-code/images/before.png&#34;
        type=&#34;&#34;
        alt=&#34;Before&#34;
        
      /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2022-12-27-til-how-to-add-custom-syntax-highlighting-rules-in-vs-code/images/after.png&#34;
        type=&#34;&#34;
        alt=&#34;After&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;It turns out we can do this with our own custom rules using &lt;code&gt;editor.tokenColorCustomizations&lt;/code&gt;.
To do this go to our settings (&lt;code&gt;settings.json&lt;/code&gt;) and add something like:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How To Add Custom Syntax Highlighting Rules in VS Code</strong></p>
<p>The other day (a few months ago) I was comparing Goland and VS Code for Golang development.
I noticed Goland by default seemed to have nicer syntax highlighting, so I started looking at
what I could do in VS Code to do this.</p>
<blockquote>
<p>Before</p>
</blockquote>
<p><img
        loading="lazy"
        src="/posts/2022-12-27-til-how-to-add-custom-syntax-highlighting-rules-in-vs-code/images/before.png"
        type=""
        alt="Before"
        
      /></p>
<blockquote>
<p>After</p>
</blockquote>
<p><img
        loading="lazy"
        src="/posts/2022-12-27-til-how-to-add-custom-syntax-highlighting-rules-in-vs-code/images/after.png"
        type=""
        alt="After"
        
      /></p>
<p>It turns out we can do this with our own custom rules using <code>editor.tokenColorCustomizations</code>.
To do this go to our settings (<code>settings.json</code>) and add something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;editor.tokenColorCustomizations&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;[Dracula]&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;textMateRules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;scope&#34;</span><span class="p">:</span> <span class="s2">&#34;source.go&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;foreground&#34;</span><span class="p">:</span> <span class="s2">&#34;#6dd8ce&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Where:</p>
<ul>
<li><code>Dracula</code> is the colour scheme</li>
<li><code>scope</code> is the type of token we want to colour</li>
</ul>
<p>We can find out what we should set the scope as by going to the command palette and selecting <code>Developer: Inspect Editor Tokens and Scopes</code>.</p>
<p><img
        loading="lazy"
        src="/posts/2022-12-27-til-how-to-add-custom-syntax-highlighting-rules-in-vs-code/images/command.png"
        type=""
        alt="Command Palette"
        
      /></p>
<p>Then go and hover over the different parts of our code and it will tell you what type of token it is <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<p><img
        loading="lazy"
        src="/posts/2022-12-27-til-how-to-add-custom-syntax-highlighting-rules-in-vs-code/images/token.png"
        type=""
        alt="Token"
        
      /></p>
<p>That&rsquo;s it!</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://blog.4d.com/setting-up-code-syntax-highlighting-using-the-visual-studio-code-extension/">https://blog.4d.com/setting-up-code-syntax-highlighting-using-the-visual-studio-code-extension/</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Connect PocketBase and BackBlaze S3</title>
      <link>https://haseebmajid.dev/posts/2022-12-26-til-how-to-connect-pocketbase-and-backblaze-s3/</link>
      <pubDate>Mon, 26 Dec 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-12-26-til-how-to-connect-pocketbase-and-backblaze-s3/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Connect PocketBase and BackBlaze S3&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;By default PocketBase uses the local file system to store uploaded files. If you have limited disk space, you could optionally connect to a S3 compatible storage. - PocketBase&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;why-backblaze-&#34;&gt;Why BackBlaze ?&lt;/h2&gt;
&lt;p&gt;Simple the prices are generally cheaper as compared with other S3 compatible storage platforms.
How can we set up BackBlaze as our S3 bucket to store uploaded files such as user avatars?&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Connect PocketBase and BackBlaze S3</strong></p>
<blockquote>
<p>By default PocketBase uses the local file system to store uploaded files. If you have limited disk space, you could optionally connect to a S3 compatible storage. - PocketBase</p>
</blockquote>
<h2 id="why-backblaze-">Why BackBlaze ?</h2>
<p>Simple the prices are generally cheaper as compared with other S3 compatible storage platforms.
How can we set up BackBlaze as our S3 bucket to store uploaded files such as user avatars?</p>
<h2 id="backblaze">BackBlaze</h2>
<p>Go to <code>BackBlaze</code></p>
<ul>
<li>Create an account</li>
<li>Create a new bucket
<ul>
<li>You should be able to make it public or private</li>
</ul>
</li>
</ul>
<p><img
        loading="lazy"
        src="/posts/2022-12-26-til-how-to-connect-pocketbase-and-backblaze-s3/images/bucket.png"
        type=""
        alt="Bucket"
        
      /></p>
<ul>
<li>Take note of the <code>endpoint</code> i.e. <code>s3.us-west-004.backblazeb2.com</code>.</li>
<li>Then go to <code>App Keys</code>
<ul>
<li>Create a new <code>Application key</code></li>
</ul>
</li>
</ul>
<p></p>
<ul>
<li>Take note of the <code>keyID</code> and <code>applicationKey</code></li>
</ul>
<h2 id="pocketbase">PocketBase</h2>
<p>Go to your PocketBase instance:</p>
<ul>
<li>Go to Settings</li>
<li>Go to File storage</li>
</ul>
<p>Add the following details</p>
<ul>
<li>In <code>ENDPOINT</code> add the endpoint above <code>https://s3.us-west-004.backblazeb2.com</code></li>
<li><code>BUCKET</code> is the name of the bucket we created before <code>ArticleTest</code></li>
<li><code>REGION</code> you can find in the URL <code>us-west-004</code></li>
<li><code>ACCESS KEY</code> is the <code>keyID</code> above</li>
<li><code>SECRET</code> is the <code>applicationKey</code> above</li>
</ul>
<p>Then click <code>Save changes</code> and you should see <code>S3 connected successfully</code>.</p>
<p>That&rsquo;s It!</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Use DinD, localhost &amp; Gitlab CI</title>
      <link>https://haseebmajid.dev/posts/2022-12-21-til-how-to-use-dind-localhost-gitlab-ci/</link>
      <pubDate>Wed, 21 Dec 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-12-21-til-how-to-use-dind-localhost-gitlab-ci/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Use DinD, localhost &amp;amp; Gitlab CI&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this post, I will go over how you can use docker-compose and Gitlab CI.
In this example, we will be running playwright tests directly on the Gitlab runner.
The tests will start a SvelteKit server also running on the Gitlab runner. The SvelteKit
server will connect to PocketBase (backend) running in docker-compose.&lt;/p&gt;
&lt;p&gt;So essentially we need a way for something running locally to connect to something running in
docker in Gitlab CI (on a runner). This is a pattern I am using in my new app &lt;a href=&#34;https://bookmarkey.app&#34;&gt;Bookmarkey&lt;/a&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Use DinD, localhost &amp; Gitlab CI</strong></p>
<p>In this post, I will go over how you can use docker-compose and Gitlab CI.
In this example, we will be running playwright tests directly on the Gitlab runner.
The tests will start a SvelteKit server also running on the Gitlab runner. The SvelteKit
server will connect to PocketBase (backend) running in docker-compose.</p>
<p>So essentially we need a way for something running locally to connect to something running in
docker in Gitlab CI (on a runner). This is a pattern I am using in my new app <a href="https://bookmarkey.app">Bookmarkey</a> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<p>Let&rsquo;s pretend we have a <code>docker-compose.yml</code> file which looks something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">pocketbase</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ghcr.io/muchobien/pocketbase:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s1">&#39;9090:8090&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./pb_data:/pb_data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">/pb_public</span><span class="w">
</span></span></span></code></pre></div><p>and our <code>package.json</code> scripts section looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;scripts&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;test&#34;</span><span class="p">:</span> <span class="s2">&#34;playwright test&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Finally the most important file let&rsquo;s look at the gitlab ci file <code>.gitlab-ci.yml</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">stages</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">test</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="nt">tests:e2e</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">test</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">only</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">merge_request</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">mcr.microsoft.com/playwright:v1.29.0-jammy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">docker:dind</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">variables</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">DOCKER_DRIVER</span><span class="p">:</span><span class="w"> </span><span class="l">overlay2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">DOCKER_HOST</span><span class="p">:</span><span class="w"> </span><span class="l">tcp://docker:2375</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">VITE_POCKET_BASE_URL</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;http://docker:9090&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">script</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="c"># ... Installing docker and docker compose</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">docker compose up -d</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">npm run test</span><span class="w">
</span></span></span></code></pre></div><p>Since all Gitlab CI jobs run in Docker. If we want to run docker-compose inside a job we need to use the dind service <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>.
We can then use docker normally i.e. using <code>docker compose</code> to start PocketBase. The most important line here is normally
to connect to PocketBase I would use <code>http://localhost:8090</code>. However, since we are using the <code>dind</code> service we need to use
<code>docker</code> instead of <code>localhost</code>. Hence this <code>VITE_POCKET_BASE_URL: 'http://docker:9090'</code>, passed to my SvelteKit app.</p>
<p>I spent about two days debugging this issue, even though I&rsquo;d solved this problem before 🤦‍♂️. So I decided to make a quick
post so hopefully you can avoid wasting your time.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://gitlab.com/banter-bus/bookmarkey/gui/-/blob/e575e5a97feb70227fd6aae366ce4fc9beacafe2/.gitlab-ci.yml">https://gitlab.com/banter-bus/bookmarkey/gui/-/blob/e575e5a97feb70227fd6aae366ce4fc9beacafe2/.gitlab-ci.yml</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Read more about <a href="/posts/20-05-01-how-to-use-dind-with-gitlab-ci/">dind here</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Use Prettier with Hugo/Golang Templates</title>
      <link>https://haseebmajid.dev/posts/2022-12-12-til-how-to-use-prettier-with-hugo-golang-templates/</link>
      <pubDate>Mon, 12 Dec 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-12-12-til-how-to-use-prettier-with-hugo-golang-templates/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Use Prettier with Hugo/Golang Templates&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you try to use prettier on a (Hugo) Golang HTML template you may get something that looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go-html-template&#34; data-lang=&#34;go-html-template&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;or&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.Params.author&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;site&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.Params.author&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$author&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.Params.author&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;site&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.Params.author&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$author_type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%T&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$author&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;or&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;eq&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$author_type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;[]string&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;eq&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$author_type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;[]interface {}&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;delimit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$author&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;, &amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$author&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;-}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;into this&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Use Prettier with Hugo/Golang Templates</strong></p>
<p>If you try to use prettier on a (Hugo) Golang HTML template you may get something that looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{-</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="na">.Params.author</span><span class="w"> </span><span class="nx">site</span><span class="na">.Params.author</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="nx">$author</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="na">.Params.author</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">default</span><span class="w"> </span><span class="nx">site</span><span class="na">.Params.author</span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="nx">$author_type</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="k">printf</span><span class="w"> </span><span class="s">&#34;%T&#34;</span><span class="w"> </span><span class="nx">$author</span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">(</span><span class="k">or</span><span class="w"> </span><span class="o">(</span><span class="k">eq</span><span class="w"> </span><span class="nx">$author_type</span><span class="w"> </span><span class="s">&#34;[]string&#34;</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="k">eq</span><span class="w"> </span><span class="nx">$author_type</span><span class="w"> </span><span class="s">&#34;[]interface {}&#34;</span><span class="o">))</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{-</span><span class="w"> </span><span class="o">(</span><span class="nx">delimit</span><span class="w"> </span><span class="nx">$author</span><span class="w"> </span><span class="s">&#34;, &#34;</span><span class="w"> </span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{-</span><span class="w"> </span><span class="nx">$author</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{-</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">-}}</span>
</span></span></code></pre></div><p>into this</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{-</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="na">.Params.author</span><span class="w"> </span><span class="nx">site</span><span class="na">.Params.author</span><span class="w"> </span><span class="cp">}}</span> <span class="cp">{{-</span><span class="w"> </span><span class="nx">$author</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="na">.Params.author</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">default</span><span class="w"> </span><span class="nx">site</span><span class="na">.Params.author</span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span> <span class="cp">{{-</span><span class="w"> </span><span class="nx">$author_type</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="k">printf</span><span class="w"> </span><span class="s">&#34;%T&#34;</span><span class="w"> </span><span class="nx">$author</span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span> <span class="cp">{{-</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="o">(</span><span class="k">or</span><span class="w"> </span><span class="o">(</span><span class="k">eq</span><span class="w"> </span><span class="nx">$author_type</span><span class="w"> </span><span class="s">&#34;[]string&#34;</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="k">eq</span><span class="w"> </span><span class="nx">$author_type</span><span class="w"> </span><span class="s">&#34;[]interface {}&#34;</span><span class="o">))</span><span class="w"> </span><span class="cp">}}</span> <span class="cp">{{-</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="o">(</span><span class="nx">delimit</span><span class="w"> </span><span class="nx">$author</span><span class="w"> </span><span class="s">&#34;, &#34;</span><span class="w"> </span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span> <span class="cp">{{-</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cp">}}</span> <span class="cp">{{-</span><span class="w"> </span><span class="nx">$author</span><span class="w"> </span><span class="cp">}}</span> <span class="cp">{{-</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span> <span class="cp">{{-</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">-}}</span>
</span></span></code></pre></div><p>This of course something we don&rsquo;t want. So let&rsquo;s use a prettier plugin that can solve this problem for us.
Let us install <code>npm install --save-dev prettier-plugin-go-template</code>.</p>
<p>Create a <code>.prettierrc</code> file with the following contents:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;overrides&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;files&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;*.html&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;options&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;parser&#34;</span><span class="p">:</span> <span class="s2">&#34;go-template&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;goTemplateBracketSpacing&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Prettier will now format our HTML files correctly, in our Hugo project.</p>
<h2 id="optional-settings">Optional Settings</h2>
<p>By default the format of our files like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">a</span>
</span></span><span class="line"><span class="cl">  <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://github.com/reorx/hugo-PaperModX/&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">rel</span><span class="o">=</span><span class="s">&#34;noopener&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">target</span><span class="o">=</span><span class="s">&#34;_blank&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">&gt;&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>If we add the following option to the <code>.prettierrc</code>, <code>&quot;bracketSameLine&quot;: true</code> then our file will look like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">a</span>
</span></span><span class="line"><span class="cl">  <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://github.com/reorx/hugo-PaperModX/&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">rel</span><span class="o">=</span><span class="s">&#34;noopener&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">target</span><span class="o">=</span><span class="s">&#34;_blank&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">&gt;&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Sometimes our file may look something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  Analytics by
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://{{ .Site.Params.goatcounter }}.goatcounter.com&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&gt;</span>Goatcounter.<span class="p">&lt;/</span><span class="nt">a</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>To fix the dangling <code>&gt;</code> we can add the following option to the <code>.prettierrc</code> file ,  <code>&quot;htmlWhitespaceSensitivity&quot;: &quot;ignore&quot;</code> then our
file will look like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  Analytics by
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://{{ .Site.Params.goatcounter }}.goatcounter.com&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Goatcounter.
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Deploy a SvelteKit site on Netlify</title>
      <link>https://haseebmajid.dev/posts/2022-12-10-til-how-to-deploy-a-sveltekit-site-on-netlify/</link>
      <pubDate>Sat, 10 Dec 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-12-10-til-how-to-deploy-a-sveltekit-site-on-netlify/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Deploy a SvelteKit site on Netlify&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So you have a SvelteKit site you want to deploy to Netlify how can we do that? First, go about setting up a site like normal!
In my case, I am going to import an existing site from Gitlab.&lt;/p&gt;
&lt;h2 id=&#34;netlify&#34;&gt;Netlify&lt;/h2&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2022-12-10-til-how-to-deploy-a-sveltekit-site-on-netlify/images/new_netlify_site.png&#34;
        type=&#34;&#34;
        alt=&#34;New Netlify Site&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;In the build settings we want the following settings:&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2022-12-10-til-how-to-deploy-a-sveltekit-site-on-netlify/images/import_site.png&#34;
        type=&#34;&#34;
        alt=&#34;Import from git&#34;
        
      /&gt;&lt;/p&gt;
&lt;details
  class=&#34;notice tip&#34;
  open=&#34;true&#34;
&gt;
    &lt;summary class=&#34;notice-title&#34;&gt;Branch&lt;/summary&gt;
  
  Adjust the branch to whatever your main branch is i.e. the branch you want to deploy from.
&lt;/details&gt;

&lt;p&gt;That&amp;rsquo;s it now our site should start deploying, and it should also set up deploy previews for MRs automatically
&lt;a href=&#34;../../posts/2022-12-03-my-workflow-to-create-a-new-post-using-hugo-netlifycms-netlify-and-gitlab-together/#netlify-preview&#34;&gt;More about that here&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Deploy a SvelteKit site on Netlify</strong></p>
<p>So you have a SvelteKit site you want to deploy to Netlify how can we do that? First, go about setting up a site like normal!
In my case, I am going to import an existing site from Gitlab.</p>
<h2 id="netlify">Netlify</h2>
<p><img
        loading="lazy"
        src="/posts/2022-12-10-til-how-to-deploy-a-sveltekit-site-on-netlify/images/new_netlify_site.png"
        type=""
        alt="New Netlify Site"
        
      /></p>
<p>In the build settings we want the following settings:</p>
<p><img
        loading="lazy"
        src="/posts/2022-12-10-til-how-to-deploy-a-sveltekit-site-on-netlify/images/import_site.png"
        type=""
        alt="Import from git"
        
      /></p>
<details
  class="notice tip"
  open="true"
>
    <summary class="notice-title">Branch</summary>
  
  Adjust the branch to whatever your main branch is i.e. the branch you want to deploy from.
</details>

<p>That&rsquo;s it now our site should start deploying, and it should also set up deploy previews for MRs automatically
<a href="/posts/2022-12-03-my-workflow-to-create-a-new-post-using-hugo-netlifycms-netlify-and-gitlab-together/#netlify-preview">More about that here</a>.</p>
<h2 id="our-project">Our Project</h2>
<p>Within our SvelteKit project if you look at <code>svelte.config.js</code> it should look something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">adapter</span> <span class="nx">from</span> <span class="s1">&#39;@sveltejs/adapter-auto&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">preprocess</span> <span class="nx">from</span> <span class="s1">&#39;svelte-preprocess&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/** @type {import(&#39;@sveltejs/kit&#39;).Config} */</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// Consult https://github.com/sveltejs/svelte-preprocess
</span></span></span><span class="line"><span class="cl">  <span class="c1">// for more information about preprocessors
</span></span></span><span class="line"><span class="cl">  <span class="nx">kit</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">adapter</span><span class="o">:</span> <span class="nx">adapter</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">preprocess</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="nx">preprocess</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">postcss</span><span class="o">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">})</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">config</span><span class="p">;</span>
</span></span></code></pre></div><p>You do not need to use the Netlify adapter here unless we need to specify specific options such as edge functions etc. However to let SvelteKit know we are using the Netlify adapter we need to pass an environment variable <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<p>We can also create a <code>netlify.toml</code> file repository to keep the settings locally rather than just on Netlify. The advantage of this is keeping
our settings in code (and version control).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">build</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">publish</span> <span class="p">=</span> <span class="s2">&#34;build&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">command</span> <span class="p">=</span> <span class="s2">&#34;npm run build&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">context</span><span class="p">.</span><span class="nx">production</span><span class="p">.</span><span class="nx">environment</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">NETLIFY</span> <span class="p">=</span> <span class="s2">&#34;true&#34;</span>
</span></span></code></pre></div><div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://github.com/sveltejs/kit/blob/master/packages/adapter-auto/adapters.js">https://github.com/sveltejs/kit/blob/master/packages/adapter-auto/adapters.js</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Separate our Golang Tests</title>
      <link>https://haseebmajid.dev/posts/2022-12-04-til-how-to-separate-our-golang-tests/</link>
      <pubDate>Sun, 04 Dec 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-12-04-til-how-to-separate-our-golang-tests/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Separate our Golang Tests&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sometimes we want to be able to run our unit tests and integration tests separately.
In Golang we can do this using build tags, build tags are used to tell the compiler
important information when we run &lt;code&gt;go build&lt;/code&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Let say we have a file called &lt;code&gt;package_test.go&lt;/code&gt;. By adding &lt;code&gt;// +build integration&lt;/code&gt; to the top of the file
without any whitespace. This test file will only be run when we specify the tags in our
test command &lt;code&gt;go test --tags=integration&lt;/code&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Separate our Golang Tests</strong></p>
<p>Sometimes we want to be able to run our unit tests and integration tests separately.
In Golang we can do this using build tags, build tags are used to tell the compiler
important information when we run <code>go build</code> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<p>Let say we have a file called <code>package_test.go</code>. By adding <code>// +build integration</code> to the top of the file
without any whitespace. This test file will only be run when we specify the tags in our
test command <code>go test --tags=integration</code>.</p>
<p>Our integration test file would look something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-golang" data-lang="golang"><span class="line"><span class="cl"><span class="c1">// +build integration</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="kn">package</span><span class="w"> </span><span class="nx">mypackage_test</span><span class="w">
</span></span></span></code></pre></div><p>Our unit tests can be left without any build tags and can be run with <code>go test</code> like normal.</p>
<p>To get this to compile correctly with VS Code we need to add the following to <code>settings.json</code> file.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;go.buildFlags&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;-tags=integration&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;go.testTags&#34;</span><span class="p">:</span> <span class="s2">&#34;integration&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>More about Golang build tags, <a href="https://mickey.dev/posts/go-build-tags-testing/">https://mickey.dev/posts/go-build-tags-testing/</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How you can Verify Your Hugo Blog on Mastodon</title>
      <link>https://haseebmajid.dev/posts/2022-11-30-til-how-you-can-verify-your-hugo-blog-on-mastodon/</link>
      <pubDate>Wed, 30 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-30-til-how-you-can-verify-your-hugo-blog-on-mastodon/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How you can Verify Your Hugo Blog on Mastodon&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Mastodon is an open-source social media website gaining a lot of traction at the moment, thanks in part to what is happening at Twitter.
On Mastodon, we can verify a link on our profile is owned by us by linking back to Mastodon with a &lt;code&gt;rel=&amp;quot;me&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2022-11-30-til-how-you-can-verify-your-hugo-blog-on-mastodon/images/mastodon_settings.png&#34;
        type=&#34;&#34;
        alt=&#34;Settings&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2022-11-30-til-how-you-can-verify-your-hugo-blog-on-mastodon/images/verification.png&#34;
        type=&#34;&#34;
        alt=&#34;Verification&#34;
        
      /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;Go to settings/profile&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;In my case, it is this, &lt;a href=&#34;https://hachyderm.io/settings/profile&#34;&gt;https://hachyderm.io/settings/profile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;Find the verification link&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;It will look something like &lt;code&gt;&amp;lt;a rel=&amp;quot;me&amp;quot; href=&amp;quot;https://hachyderm.io/@majiy00&amp;quot;&amp;gt;Mastodon&amp;lt;/a&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Yours may look different if you are on a different Mastodon instance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Copy this into our site
&lt;ul&gt;
&lt;li&gt;For example, in your footer &lt;code&gt;footer.html&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go-html-template&#34; data-lang=&#34;go-html-template&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;display: inline-block; margin-left: 1em;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Powered by
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://gohugo.io/&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;rel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;noopener noreferrer&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;_blank&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Hugo&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://github.com/reorx/hugo-PaperModX/&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;rel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;noopener&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;_blank&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;PaperModX&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;rel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;me&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://hachyderm.io/@majiy00&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Mastodon&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.Site.Params.goatcounter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        Analytics by &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;.Site.Params.goatcounter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;.goatcounter.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Goatcounter&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cp&#34;&gt;{{-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;papermod&#34;&gt;PaperMod&lt;/h2&gt;
&lt;p&gt;If you are using the &lt;a href=&#34;https://adityatelange.github.io/hugo-PaperMod/&#34;&gt;PaperMod&lt;/a&gt; theme or similar.
You can make this change to the &lt;code&gt;config.yml&lt;/code&gt;:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How you can Verify Your Hugo Blog on Mastodon</strong></p>
<p>Mastodon is an open-source social media website gaining a lot of traction at the moment, thanks in part to what is happening at Twitter.
On Mastodon, we can verify a link on our profile is owned by us by linking back to Mastodon with a <code>rel=&quot;me&quot;</code>.</p>
<p><img
        loading="lazy"
        src="/posts/2022-11-30-til-how-you-can-verify-your-hugo-blog-on-mastodon/images/mastodon_settings.png"
        type=""
        alt="Settings"
        
      /></p>
<p><img
        loading="lazy"
        src="/posts/2022-11-30-til-how-you-can-verify-your-hugo-blog-on-mastodon/images/verification.png"
        type=""
        alt="Verification"
        
      /></p>
<ul>
<li>
<ol>
<li>Go to settings/profile</li>
</ol>
<ul>
<li>In my case, it is this, <a href="https://hachyderm.io/settings/profile">https://hachyderm.io/settings/profile</a></li>
</ul>
</li>
<li>
<ol>
<li>Find the verification link</li>
</ol>
<ul>
<li>It will look something like <code>&lt;a rel=&quot;me&quot; href=&quot;https://hachyderm.io/@majiy00&quot;&gt;Mastodon&lt;/a&gt;</code>
<ul>
<li>Yours may look different if you are on a different Mastodon instance</li>
</ul>
</li>
</ul>
</li>
<li>Copy this into our site
<ul>
<li>For example, in your footer <code>footer.html</code></li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">span</span> <span class="na">style</span><span class="o">=</span><span class="s">&#34;display: inline-block; margin-left: 1em;&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Powered by
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://gohugo.io/&#34;</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;noopener noreferrer&#34;</span> <span class="na">target</span><span class="o">=</span><span class="s">&#34;_blank&#34;</span><span class="p">&gt;</span>Hugo<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> <span class="err">&amp;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://github.com/reorx/hugo-PaperModX/&#34;</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;noopener&#34;</span> <span class="na">target</span><span class="o">=</span><span class="s">&#34;_blank&#34;</span><span class="p">&gt;</span>PaperModX<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>.
</span></span><span class="line hl"><span class="cl">    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;me&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://hachyderm.io/@majiy00&#34;</span><span class="p">&gt;</span>Mastodon<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{-</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="na">.Site.Params.goatcounter</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        Analytics by <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Site.Params.goatcounter</span><span class="w"> </span><span class="cp">}}</span><span class="s">.goatcounter.com&#34;</span><span class="p">&gt;</span>Goatcounter<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>.
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{-</span><span class="w"> </span><span class="k">end</span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div><h2 id="papermod">PaperMod</h2>
<p>If you are using the <a href="https://adityatelange.github.io/hugo-PaperMod/">PaperMod</a> theme or similar.
You can make this change to the <code>config.yml</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># ...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">socialIcons</span><span class="p">:</span><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">gitlab</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://gitlab.com/hmajid2301&#34;</span><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">github</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://github.com/hmajid2301&#34;</span><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">linkedin</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://www.linkedin.com/in/haseeb-majid-ba0a5194/&#34;</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">mastodon</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://hachyderm.io/@majiy00&#34;</span><span class="w">
</span></span></span></code></pre></div><p>If you drill down into the code you will see these get turned into anchors tags in <code>social_icons.html</code> page, like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="nx">trim</span><span class="w"> </span><span class="na">.url</span><span class="w"> </span><span class="s">&#34; &#34;</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span> <span class="na">target</span><span class="o">=</span><span class="s">&#34;_blank&#34;</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;noopener noreferrer me&#34;</span> <span class="na">title</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.name</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">title</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{</span><span class="w"> </span><span class="nx">safeHTML</span><span class="w"> </span><span class="o">(</span><span class="k">index</span><span class="w"> </span><span class="na">$.svg</span><span class="w"> </span><span class="nx">$icon_name</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">default</span><span class="w"> </span><span class="na">$.svg.default</span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Fix &#34;Overflowing&#34; Highlights in Hugo Code Blocks</title>
      <link>https://haseebmajid.dev/posts/2022-11-27-til-how-to-fix-overflowing-highlights-in-hugo-code-blocks/</link>
      <pubDate>Sun, 27 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-27-til-how-to-fix-overflowing-highlights-in-hugo-code-blocks/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Fix &amp;ldquo;Overflowing&amp;rdquo; Highlights in Hugo Code Blocks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I am using the &lt;a href=&#34;https://reorx.github.io/hugo-PaperModX/&#34;&gt;PaperModX&lt;/a&gt; theme, or at least a theme that is very close to that theme.
I noticed an issue when I would try to highlight my code in code blocks. For example, if we had the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;``&lt;span class=&#34;sb&#34;&gt;`js {hl_lines=[1]}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;const images = Array.from(document.querySelectorAll(&amp;#34;.post-content img&amp;#34;));
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;\`&lt;/span&gt;``
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It would highlight line number the first line in the code block but just up to the width of the code block.
So if you scrolled to the right to see the rest of the code it would not be highlighted.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Fix &ldquo;Overflowing&rdquo; Highlights in Hugo Code Blocks</strong></p>
<p>I am using the <a href="https://reorx.github.io/hugo-PaperModX/">PaperModX</a> theme, or at least a theme that is very close to that theme.
I noticed an issue when I would try to highlight my code in code blocks. For example, if we had the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">``<span class="sb">`js {hl_lines=[1]}
</span></span></span><span class="line"><span class="cl"><span class="sb">const images = Array.from(document.querySelectorAll(&#34;.post-content img&#34;));
</span></span></span><span class="line"><span class="cl"><span class="sb">\`</span>``
</span></span></code></pre></div><p>It would highlight line number the first line in the code block but just up to the width of the code block.
So if you scrolled to the right to see the rest of the code it would not be highlighted.</p>
<p><img
        loading="lazy"
        src="/posts/2022-11-27-til-how-to-fix-overflowing-highlights-in-hugo-code-blocks/images/hugo_code_blocks.png"
        type=""
        alt="Hugo Code Blocks Highlighting"
        
      /></p>
<p>This doesn&rsquo;t look great so let&rsquo;s fix it, find your CSS code that does the styling for the code blocks.
In my case it is called <code>assets/css/lib/chroma-dark.css</code> and <code>assets/css/lib/chroma-light.css</code>.</p>
<p>Then in the <code>LineHighlight</code> part add <code>width: max-content;</code> so my light theme files looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="c">/* LineHighlight */</span> <span class="p">.</span><span class="nc">chroma</span> <span class="p">.</span><span class="nc">hl</span> <span class="p">{</span> <span class="k">background-color</span><span class="p">:</span> <span class="mh">#ffffcc</span><span class="p">;</span> <span class="k">width</span><span class="p">:</span> <span class="n">max-content</span><span class="p">;</span> <span class="p">}</span>
</span></span></code></pre></div><p>and my dark theme file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="c">/* LineHighlight */</span> <span class="p">.</span><span class="nc">chroma</span> <span class="p">.</span><span class="nc">hl</span> <span class="p">{</span> <span class="k">background-color</span><span class="p">:</span> <span class="mh">#bd93f9</span><span class="mi">40</span><span class="p">;</span> <span class="k">width</span><span class="p">:</span> <span class="n">max-content</span><span class="p">;</span> <span class="p">}</span>
</span></span></code></pre></div><p>Now it looks like this:</p>
<p><img
        loading="lazy"
        src="/posts/2022-11-27-til-how-to-fix-overflowing-highlights-in-hugo-code-blocks/images/hugo_code_blocks_fixed.png"
        type=""
        alt="Hugo Code Blocks Highlighting Fixed"
        
      /></p>
<p>That&rsquo;s it!</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How to Add Hugo Shortcode Snippets in VSCode</title>
      <link>https://haseebmajid.dev/posts/2022-11-26-til-how-to-add-hugo-shortcode-snippets-in-vscode/</link>
      <pubDate>Sat, 26 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-26-til-how-to-add-hugo-shortcode-snippets-in-vscode/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How to Add Hugo Shortcode Snippets in VSCode&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hugo &lt;a href=&#34;https://gohugo.io/content-management/shortcodes/&#34;&gt;shortcodes&lt;/a&gt; are a great way to add functionality to our Hugo blog.
However, I find them fiddly to add.&lt;/p&gt;
&lt;p&gt;So let&amp;rsquo;s see how we can leverage VSCode snippets to make it easier to add shortcodes to our markdown files.
First, open the command palette, then select &lt;code&gt;Snippets: Configure User Snippets&lt;/code&gt;. In my case, I want to add snippets
specific to this project so I select &lt;code&gt;New snippets file for &#39;&amp;lt;project&amp;gt;&#39;&lt;/code&gt;. Give it a name like &lt;code&gt;shortcodes&lt;/code&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How to Add Hugo Shortcode Snippets in VSCode</strong></p>
<p>Hugo <a href="https://gohugo.io/content-management/shortcodes/">shortcodes</a> are a great way to add functionality to our Hugo blog.
However, I find them fiddly to add.</p>
<p>So let&rsquo;s see how we can leverage VSCode snippets to make it easier to add shortcodes to our markdown files.
First, open the command palette, then select <code>Snippets: Configure User Snippets</code>. In my case, I want to add snippets
specific to this project so I select <code>New snippets file for '&lt;project&gt;'</code>. Give it a name like <code>shortcodes</code>.</p>
<p>This will create a new file in <code>.vscode/shortcodes.code-snippets</code>.
Then I will update the file to make it look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;invidious&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;prefix&#34;</span><span class="p">:</span> <span class="s2">&#34;invidious&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;body&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;{{&lt; invidious ${1:link} &gt;}}&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;invidious Hugo shortcode&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;notice&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;prefix&#34;</span><span class="p">:</span> <span class="s2">&#34;notice&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;body&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;{{&lt; notice type=\&#34;${1:type}\&#34; title=\&#34;${3:title}\&#34; &gt;}}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;${4:content}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;{{&lt; notice &gt;}}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;$0&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;notice Hugo shortcode&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Which could then easily be turned into this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">{{<span class="p">&lt;</span> <span class="nt">notice</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;warning&#34;</span> <span class="na">title</span><span class="o">=</span><span class="s">&#34;warning&#34;</span> <span class="p">&gt;</span>}}
</span></span><span class="line"><span class="cl">This is a warning
</span></span><span class="line"><span class="cl">{{<span class="p">&lt;</span> <span class="p">/</span><span class="nt">notice</span> <span class="p">&gt;</span>}}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{<span class="p">&lt;</span> <span class="nt">invidious</span> <span class="na">rALo_BzGKs8</span> <span class="p">&gt;</span>}}
</span></span></code></pre></div><p>To add them to our markdown files we just need to type the prefix i.e. <code>notice</code> and then press the auto-complete button i.e. <code>tab</code>.
However, we may need to turn on autocomplete for markdown files in our <code>settings.json</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;[markdown]&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;editor.quickSuggestions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;other&#34;</span><span class="p">:</span> <span class="s2">&#34;on&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;comments&#34;</span><span class="p">:</span> <span class="s2">&#34;off&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;strings&#34;</span><span class="p">:</span> <span class="s2">&#34;off&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>🙌 That&rsquo;s it! You should be able to use the code snippets more easily add shortcodes!</p>
<h2 id="optional-extensions">(Optional) Extensions</h2>
<p>I also use the following extensions with VSCode (specifically for Hugo):</p>
<ul>
<li><a href="https://marketplace.visualstudio.com/items?itemName=budparr.language-hugo-vscode"><code>Hugo Language and Syntax Support</code></a>: Adds snippets for builtin Hugo shortcodes i.e. <code>highlight</code></li>
<li><a href="https://marketplace.visualstudio.com/items?itemName=kaellarkin.hugo-shortcode-syntax"><code>Hugo Shortcode Syntax Highlighting</code></a>: Adds syntax highlighting for shortcodes in markdown files</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: You Can Schedule Posts on Your Hugo Blog using Netlify and Gitlab CI</title>
      <link>https://haseebmajid.dev/posts/2022-11-23-til-you-can-schedule-posts-on-your-hugo-blog-using-netlify-and-gitlab-ci/</link>
      <pubDate>Wed, 23 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-23-til-you-can-schedule-posts-on-your-hugo-blog-using-netlify-and-gitlab-ci/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: You Can Schedule Posts on Your Hugo Blog using Netlify and Gitlab CI&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This post in fact will be a scheduled post I&amp;rsquo;m writing it on the 20th of November but it will be published on the 23rd of November.
Assuming we are using Netlify to deploy our website, what we will need to do is trigger a rebuild of our site every day using Gitlab CI.
Since Hugo builds a static site to publish our content after a set date we will need to rebuild our site. So let&amp;rsquo;s see how we can automate
that. Else the post won&amp;rsquo;t be visible until I next make a commit to my main branch.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: You Can Schedule Posts on Your Hugo Blog using Netlify and Gitlab CI</strong></p>
<p>This post in fact will be a scheduled post I&rsquo;m writing it on the 20th of November but it will be published on the 23rd of November.
Assuming we are using Netlify to deploy our website, what we will need to do is trigger a rebuild of our site every day using Gitlab CI.
Since Hugo builds a static site to publish our content after a set date we will need to rebuild our site. So let&rsquo;s see how we can automate
that. Else the post won&rsquo;t be visible until I next make a commit to my main branch.</p>
<p>I use the <code>date</code> field to determine when to make this post visible on my blog, set in the front matter of the post (markdown).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;TIL: You Can Schedule Posts on Your Hugo Blog using Netlify and Gitlab CI&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">canonicalURL</span><span class="p">:</span><span class="w"> </span><span class="l">https://haseebmajid.dev/posts/2022-11-23-til-you-can-schedule-posts-on-your-hugo-blog-using-netlify-and-gitlab-ci/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">date</span><span class="p">:</span><span class="w"> </span><span class="ld">2022-11-23</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span></code></pre></div><p>We can do this by first creating a build hook on Netlify, go to your <code>Site Settings</code> (on Netlify) then <code>Build and Deploy</code>. Copy the build hook
cURL request example which will look like <code>curl -X POST -d {} https://api.netlify.com/build_hooks/[id]</code>.</p>
<p><img
        loading="lazy"
        src="/posts/2022-11-23-til-you-can-schedule-posts-on-your-hugo-blog-using-netlify-and-gitlab-ci/images/netlify_build_hook.png"
        type=""
        alt="Netlify Build Hook"
        
      /></p>
<p>Next, go to Gitlab and open your <code>Settings &gt; CI/CD</code> settings and add a new variable called <code>NETLIFY_DEPLOY_WEBHOOK</code> and copy your build hook URL
<code>https://api.netlify.com/build_hooks/[id]</code>. Mark the variable as protected.</p>
<p><img
        loading="lazy"
        src="/posts/2022-11-23-til-you-can-schedule-posts-on-your-hugo-blog-using-netlify-and-gitlab-ci/images/gitlab_ci_variables.png"
        type=""
        alt="Gitlab CI Variables"
        
      /></p>
<p>Then update our <code>.gitlab-ci.yml</code> with the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="nt">stages</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">deploy</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="nt">deploy_site</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">deploy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">curl</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">variables</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">GIT_STRATEGY</span><span class="p">:</span><span class="w"> </span><span class="l">none</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">script</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">curl -X POST -d &#39;{}&#39; $NETLIFY_BUILD_WEBHOOK</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">only</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">schedules</span><span class="w">
</span></span></span></code></pre></div><p>This job will run on a schedule, i.e. once a day, that will trigger the build hook and cause Netlify to rebuild our site.
This means any posts due to be published that day will be visible on our site.</p>
<p>Finally, let&rsquo;s schedule our CI job, go to <code>CI/CD &gt; Schedules</code>, and then create a new schedule. Set the <a href="https://crontab.guru">cron</a> to whatever
you want. My pipeline schedule is set as so:</p>
<p><img
        loading="lazy"
        src="/posts/2022-11-23-til-you-can-schedule-posts-on-your-hugo-blog-using-netlify-and-gitlab-ci/images/gitlab_ci_schedule.png"
        type=""
        alt="Gitlab CI Schedule"
        
      /></p>
<p>This will cause our website to build once a day, triggering a build on Netlify. So when the Gitlab CI job runs at midnight on the 23rd of November
this post will be visible to you all.</p>
<p>You can test your website using the <code>--buildFuture</code> flag i.e. <code>hugo server -D --buildFuture</code> when testing your site locally.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://hamy.xyz/labs/hugo-schedule-rebuilds-on-netlify">Inspired by</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: You can add a custom domain to your Goatcounter site</title>
      <link>https://haseebmajid.dev/posts/2022-11-22-til-you-can-add-a-custom-domain-to-your-goatcounter-site/</link>
      <pubDate>Tue, 22 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-22-til-you-can-add-a-custom-domain-to-your-goatcounter-site/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: You can add a custom domain to your Goatcounter site&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you create an account on Goatcounter and add a new site, you can view the analytics by going to &lt;code&gt;[sitecode].goatcounter.com&lt;/code&gt;.
For example, &lt;a href=&#34;https://haseebmajid.goatcounter.com&#34;&gt;&lt;code&gt;haseebmajid.goatcounter.com&lt;/code&gt;&lt;/a&gt;. However, we can use a custom domain, to view your analytics.&lt;/p&gt;
&lt;details
  class=&#34;notice warning&#34;
  open=&#34;true&#34;
&gt;
    &lt;summary class=&#34;notice-title&#34;&gt;Custom Domain&lt;/summary&gt;
  
  You will need a domain, that you can control the DNS of to do the following!
&lt;/details&gt;

&lt;h2 id=&#34;goatcounter&#34;&gt;Goatcounter&lt;/h2&gt;
&lt;p&gt;We can do this by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First go to your Goatcounter site
&lt;ul&gt;
&lt;li&gt;i.e. &lt;code&gt;haseebmajid.goatcounter.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Then go to &lt;code&gt;Settings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Then &lt;code&gt;Domain settings&lt;/code&gt; &amp;gt; &lt;code&gt;Custom domain&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Add your domain
&lt;ul&gt;
&lt;li&gt;i.e. &lt;code&gt;stats.haseebmajid.dev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Press the &lt;code&gt;Save&lt;/code&gt; button on the bottom left&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&#34;position:relative;padding-bottom:calc(100% / 1.78)&#34;&gt;
  &lt;iframe
    src=&#34;https://gfycat.com/ifr/InsignificantMemorableGreathornedowl&#34;
    frameborder=&#34;0&#34;
    scrolling=&#34;no&#34;
    width=&#34;100%&#34;
    height=&#34;100%&#34;
    style=&#34;position:absolute;top:0;left:0;&#34;
    allowfullscreen
  &gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;h2 id=&#34;domain&#34;&gt;Domain&lt;/h2&gt;
&lt;p&gt;Finally, we need to go to our domain management tool, such as &lt;code&gt;namecheap&lt;/code&gt; and add a new entry:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: You can add a custom domain to your Goatcounter site</strong></p>
<p>When you create an account on Goatcounter and add a new site, you can view the analytics by going to <code>[sitecode].goatcounter.com</code>.
For example, <a href="https://haseebmajid.goatcounter.com"><code>haseebmajid.goatcounter.com</code></a>. However, we can use a custom domain, to view your analytics.</p>
<details
  class="notice warning"
  open="true"
>
    <summary class="notice-title">Custom Domain</summary>
  
  You will need a domain, that you can control the DNS of to do the following!
</details>

<h2 id="goatcounter">Goatcounter</h2>
<p>We can do this by:</p>
<ul>
<li>First go to your Goatcounter site
<ul>
<li>i.e. <code>haseebmajid.goatcounter.com</code></li>
</ul>
</li>
<li>Then go to <code>Settings</code></li>
<li>Then <code>Domain settings</code> &gt; <code>Custom domain</code>
<ul>
<li>Add your domain
<ul>
<li>i.e. <code>stats.haseebmajid.dev</code></li>
</ul>
</li>
</ul>
</li>
<li>Press the <code>Save</code> button on the bottom left</li>
</ul>
<div style="position:relative;padding-bottom:calc(100% / 1.78)">
  <iframe
    src="https://gfycat.com/ifr/InsignificantMemorableGreathornedowl"
    frameborder="0"
    scrolling="no"
    width="100%"
    height="100%"
    style="position:absolute;top:0;left:0;"
    allowfullscreen
  ></iframe>
</div>

<h2 id="domain">Domain</h2>
<p>Finally, we need to go to our domain management tool, such as <code>namecheap</code> and add a new entry:</p>
<ul>
<li><code>CNAME stats.haseebmajid.dev haseebmajid.goatcounter.com</code></li>
</ul>
<details
  class="notice tip"
  open="true"
>
    <summary class="notice-title">Certificate</summary>
  
  It can up to an hour for the certificate to be created so try to visit your page in an hour.
</details>

]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How You Can Zoom in on Photos in your Hugo Posts</title>
      <link>https://haseebmajid.dev/posts/2022-11-21-til-how-you-can-zoom-in-on-photos-in-your-hugo-posts/</link>
      <pubDate>Mon, 21 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-21-til-how-you-can-zoom-in-on-photos-in-your-hugo-posts/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How You Can Zoom in on Photos in your Hugo Posts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can see what we want to achieve in the GIF below:&lt;/p&gt;
&lt;div style=&#34;position:relative;padding-bottom:calc(100% / 1.78)&#34;&gt;
  &lt;iframe
    src=&#34;https://gfycat.com/ifr/MisguidedFondDingo&#34;
    frameborder=&#34;0&#34;
    scrolling=&#34;no&#34;
    width=&#34;100%&#34;
    height=&#34;100%&#34;
    style=&#34;position:absolute;top:0;left:0;&#34;
    allowfullscreen
  &gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;h2 id=&#34;how&#34;&gt;How?&lt;/h2&gt;
&lt;p&gt;Add the following code to your Hugo blog in my case using the Papermod theme I add it to the &lt;code&gt;layouts/partials/extend_footer.html&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://cdnjs.cloudflare.com/ajax/libs/medium-zoom/1.0.6/medium-zoom.min.js&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;integrity&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;sha512-N9IJRoc3LaP3NDoiGkcPa4gG94kapGpaA5Zq9/Dr04uf5TbLFU5q0o8AbRhLKUUlp8QFS2u7S+Yti0U7QtuZvQ==&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;crossorigin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;anonymous&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;referrerpolicy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;no-referrer&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;images&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.post-content img&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;forEach&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;mediumZoom&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;margin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;cm&#34;&gt;/* The space outside the zoomed image */&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;scrollOffset&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;40&lt;/span&gt; &lt;span class=&#34;cm&#34;&gt;/* The number of pixels to scroll to close the zoom */&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;container&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;cm&#34;&gt;/* The viewport to render the zoom in */&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;cm&#34;&gt;/* The template element to display on zoom */&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;background&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;rgba(0, 0, 0, 0.8)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The highlighted line may need to change depending on how your blog is setup. For my blog using the
&lt;a href=&#34;https://github.com/adityatelange/hugo-PaperMod&#34;&gt;PaperMod&lt;/a&gt; theme. This gets all the images on the page
&lt;code&gt;.post-content img&lt;/code&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How You Can Zoom in on Photos in your Hugo Posts</strong></p>
<p>You can see what we want to achieve in the GIF below:</p>
<div style="position:relative;padding-bottom:calc(100% / 1.78)">
  <iframe
    src="https://gfycat.com/ifr/MisguidedFondDingo"
    frameborder="0"
    scrolling="no"
    width="100%"
    height="100%"
    style="position:absolute;top:0;left:0;"
    allowfullscreen
  ></iframe>
</div>

<h2 id="how">How?</h2>
<p>Add the following code to your Hugo blog in my case using the Papermod theme I add it to the <code>layouts/partials/extend_footer.html</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span>
</span></span><span class="line"><span class="cl">  <span class="na">src</span><span class="o">=</span><span class="s">&#34;https://cdnjs.cloudflare.com/ajax/libs/medium-zoom/1.0.6/medium-zoom.min.js&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">integrity</span><span class="o">=</span><span class="s">&#34;sha512-N9IJRoc3LaP3NDoiGkcPa4gG94kapGpaA5Zq9/Dr04uf5TbLFU5q0o8AbRhLKUUlp8QFS2u7S+Yti0U7QtuZvQ==&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">crossorigin</span><span class="o">=</span><span class="s">&#34;anonymous&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">referrerpolicy</span><span class="o">=</span><span class="s">&#34;no-referrer&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line hl"><span class="cl">  <span class="kr">const</span> <span class="nx">images</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">from</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelectorAll</span><span class="p">(</span><span class="s2">&#34;.post-content img&#34;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">  <span class="nx">images</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">img</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">mediumZoom</span><span class="p">(</span><span class="nx">img</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">margin</span><span class="o">:</span> <span class="mi">0</span> <span class="cm">/* The space outside the zoomed image */</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">scrollOffset</span><span class="o">:</span> <span class="mi">40</span> <span class="cm">/* The number of pixels to scroll to close the zoom */</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">container</span><span class="o">:</span> <span class="kc">null</span> <span class="cm">/* The viewport to render the zoom in */</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="kc">null</span> <span class="cm">/* The template element to display on zoom */</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">background</span><span class="o">:</span> <span class="s2">&#34;rgba(0, 0, 0, 0.8)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The highlighted line may need to change depending on how your blog is setup. For my blog using the
<a href="https://github.com/adityatelange/hugo-PaperMod">PaperMod</a> theme. This gets all the images on the page
<code>.post-content img</code>.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://github.com/adityatelange/hugo-PaperMod/issues/384#issuecomment-899219940">Github Issue w/ Solution</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: How you can add goatcounter to your Hugo blog</title>
      <link>https://haseebmajid.dev/posts/2022-11-20-til-how-you-can-add-goatcounter-to-your-hugo-blog/</link>
      <pubDate>Sun, 20 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-20-til-how-you-can-add-goatcounter-to-your-hugo-blog/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL: How you can add goatcounter to your Hugo blog&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this TIL post, we will go over how you can add Goatcounter to your Hugo Blog.
Goatcounter is an open-source privacy-friendly analytics tool, an alternative
to Google Analytics.&lt;/p&gt;
&lt;details
  class=&#34;notice warning&#34;
  open=&#34;true&#34;
&gt;
    &lt;summary class=&#34;notice-title&#34;&gt;Goatcounter Account&lt;/summary&gt;
  
  This post assumes you have already created a Goatcounter account,
&lt;a href=&#34;https://www.goatcounter.com/&#34;&gt;more information here&lt;/a&gt;.
&lt;/details&gt;

&lt;p&gt;Luckily it is very easy to add Goatcounter to our blog. First, create a new &lt;code&gt;partial&lt;/code&gt; HTML file. In my example, it will be at &lt;code&gt;layouts/partial/analytics.html&lt;/code&gt;. However, you can call and place your file where ever you want, just remember it for later.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL: How you can add goatcounter to your Hugo blog</strong></p>
<p>In this TIL post, we will go over how you can add Goatcounter to your Hugo Blog.
Goatcounter is an open-source privacy-friendly analytics tool, an alternative
to Google Analytics.</p>
<details
  class="notice warning"
  open="true"
>
    <summary class="notice-title">Goatcounter Account</summary>
  
  This post assumes you have already created a Goatcounter account,
<a href="https://www.goatcounter.com/">more information here</a>.
</details>

<p>Luckily it is very easy to add Goatcounter to our blog. First, create a new <code>partial</code> HTML file. In my example, it will be at <code>layouts/partial/analytics.html</code>. However, you can call and place your file where ever you want, just remember it for later.</p>
<p>The contents of the file should look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;partials/analytics.html&#34;</span> 
</span></span><span class="line"><span class="cl">  <span class="na">data-goatcounter</span><span class="o">=</span><span class="s">&#34;https://{{ .Site.Params.goatcounter }}.goatcounter.com/count&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">async</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;//gc.zgo.at/count.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><blockquote>
<p>We will see how to pass the <code>goatcounter</code> param, later on, the <code>{{ .Site.Params.goatcounter }}</code></p>
</blockquote>
<p>Next, go look for a file which is used as the template for all of our pages.
In my case, it is located at <code>layouts/_default/baseof.html</code> and add the
following just above your footer:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="nx">partialCached</span><span class="w"> </span><span class="s">&#34;header.html&#34;</span><span class="w"> </span><span class="na">.</span><span class="w"> </span><span class="na">.Page</span><span class="w"> </span><span class="cp">-}}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">main</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;main </span><span class="cp">{{-</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">(</span><span class="k">eq</span><span class="w"> </span><span class="na">.Kind</span><span class="w"> </span><span class="s">`page`</span><span class="o">)</span><span class="w"> </span><span class="cp">-}}{{-</span><span class="w"> </span><span class="k">print</span><span class="w"> </span><span class="s">&#34; post&#34;</span><span class="w"> </span><span class="cp">-}}{{-</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">-}}</span><span class="s">&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="cp">{{-</span><span class="w"> </span><span class="k">block</span><span class="w"> </span><span class="s">&#34;main&#34;</span><span class="w"> </span><span class="na">.</span><span class="w"> </span><span class="cp">}}{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line hl"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="na">.Site.Params.goatcounter</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line hl"><span class="cl">      <span class="cp">{{</span><span class="w"> </span><span class="nx">partial</span><span class="w"> </span><span class="s">&#34;analytics.html&#34;</span><span class="w"> </span><span class="na">.</span><span class="w"> </span><span class="cp">-}}</span>
</span></span><span class="line hl"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="k">end</span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="nx">partial</span><span class="w"> </span><span class="s">&#34;footer.html&#34;</span><span class="w"> </span><span class="na">.</span><span class="w"> </span><span class="cp">-}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="nx">partial</span><span class="w"> </span><span class="s">&#34;search.html&#34;</span><span class="w"> </span><span class="na">.</span><span class="w"> </span><span class="cp">-}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{-</span><span class="w"> </span><span class="k">block</span><span class="w"> </span><span class="s">&#34;body_end&#34;</span><span class="w"> </span><span class="na">.</span><span class="w"> </span><span class="cp">}}</span>
</span></span></code></pre></div><details
  class="notice tip"
  open="true"
>
    <summary class="notice-title">File Names</summary>
  
  Note here the file location and name here <code>{{ partial &quot;analytics.html&quot; . -}}</code>, matches what I said above.
</details>

<p>Finally, open your <code>config.yml</code> or <code>config.toml</code> and add the following. This is your site code on Goatcounter.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># ...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">goatcounter</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;haseebmajid&#34;</span><span class="w">
</span></span></span></code></pre></div><p>You can find your site code in your <code>settings &gt; sites</code>.</p>
<p><img
        loading="lazy"
        src="/posts/2022-11-20-til-how-you-can-add-goatcounter-to-your-hugo-blog/images/goatcounter.png"
        type=""
        alt="Goatcounter"
        
      /></p>
<p>That&rsquo;s it we&rsquo;ve added Goatcounter to our Hugo blog.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://stats.haseebmajid.dev/">Example Goatcounter</a></li>
<li><a href="https://gitlab.com/hmajid2301/blog/-/tree/ea855a0c897e6238a6642507abb6ad92bd66e2c9">Blog using Goatcounter with Hugo</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: You can use Use `yq` to Mass Edit Markdown Files</title>
      <link>https://haseebmajid.dev/posts/2022-11-17-til-you-can-use-yq-to-mass-edit-markdown-files/</link>
      <pubDate>Thu, 17 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-17-til-you-can-use-yq-to-mass-edit-markdown-files/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL you can use &lt;code&gt;yq&lt;/code&gt; to mass edit markdown files&lt;/strong&gt;&lt;/p&gt;
&lt;details
  class=&#34;notice tip&#34;
  open=&#34;false&#34;
&gt;
    &lt;summary class=&#34;notice-title&#34;&gt;yq&lt;/summary&gt;
  
  &lt;code&gt;yq&lt;/code&gt; is a tool similar to &lt;code&gt;jq&lt;/code&gt; except it allows you to edit, JSON, XML and YAML.
It has a very similar syntax to parse and edit files as &lt;code&gt;jq&lt;/code&gt; does.
&lt;/details&gt;

&lt;p&gt;I was recently adding new open graph images to all of my blog posts. After creating these images and storing them
next to the post, where the structure looks like:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL you can use <code>yq</code> to mass edit markdown files</strong></p>
<details
  class="notice tip"
  open="false"
>
    <summary class="notice-title">yq</summary>
  
  <code>yq</code> is a tool similar to <code>jq</code> except it allows you to edit, JSON, XML and YAML.
It has a very similar syntax to parse and edit files as <code>jq</code> does.
</details>

<p>I was recently adding new open graph images to all of my blog posts. After creating these images and storing them
next to the post, where the structure looks like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">content/posts/2020-01-13-using-tox-with-a-makefile-to-automate-python-related-tasks/
</span></span><span class="line"><span class="cl">├── images
</span></span><span class="line"><span class="cl">│   └── cover.png
</span></span><span class="line"><span class="cl">└── index.md
</span></span></code></pre></div><p>Now I needed to add the following to my frontmatter for all of my posts so from this</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;TIL: You can use Use `yq` to Mass Edit Markdown Files&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span></code></pre></div><p>to this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;TIL: You can use Use `yq` to Mass Edit Markdown Files&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">cover</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">images/cover.png</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span></code></pre></div><p>If I wanted to edit just that single post we could do something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">yq --front-matter<span class="o">=</span><span class="s2">&#34;process&#34;</span> -i <span class="s1">&#39;.cover.image = &#34;images/cover.png&#34;&#39;</span> content/posts/2020-01-13-using-tox-with-a-makefile-to-automate-python-related-tasks/index.md
</span></span></code></pre></div><p>Now I have ~50 odd posts I need to edit I don&rsquo;t want to run this command manually for each 😨.
Nobody wants to do that, so instead, we can run the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">find -name  <span class="s2">&#34;index.md&#34;</span> -exec yq --front-matter<span class="o">=</span><span class="s2">&#34;process&#34;</span> -i <span class="s1">&#39;.cover.image = &#34;images/cover.png&#34;&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Or using fd a find alternative</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">fd <span class="s2">&#34;index.md&#34;</span> -x yq --front-matter<span class="o">=</span><span class="s2">&#34;process&#34;</span> -i <span class="s1">&#39;.cover.image = &#34;images/cover.png&#34;&#39;</span>
</span></span></code></pre></div><p>That&rsquo;s it, we just added a cover image to the frontmatter in all of our posts 😊.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://roneo.org/en/hugo-edit-yaml-files-from-the-cli-with-yq/">Inspiration for this post</a></li>
<li><a href="https://github.com/mikefarah/yq">yq</a></li>
<li><a href="https://github.com/sharkdp/fd">fd</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: You can Hash `None` in Python? What?</title>
      <link>https://haseebmajid.dev/posts/2022-11-15-til-you-can-hash-none-in-python-what/</link>
      <pubDate>Tue, 15 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-15-til-you-can-hash-none-in-python-what/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL you can hash &lt;code&gt;None&lt;/code&gt; in Python&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recently I saw some Python code which looked something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;another_key&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;another_value&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It had never really occurred to me you could use &lt;code&gt;None&lt;/code&gt; (null) as a key to a dictionary before.
What this also meant is that &lt;code&gt;None&lt;/code&gt; must be hashable as only hashable objects can be keys in a dictionary.
These objects include &lt;code&gt;strings&lt;/code&gt;, &lt;code&gt;tuples&lt;/code&gt;, &lt;code&gt;sets&lt;/code&gt; but don&amp;rsquo;t include &lt;code&gt;lists&lt;/code&gt; as they are mutable and not
hashable.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL you can hash <code>None</code> in Python</strong></p>
<p>Recently I saw some Python code which looked something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">d</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kc">None</span><span class="p">:</span> <span class="s2">&#34;value&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;another_key&#34;</span><span class="p">:</span> <span class="s2">&#34;another_value&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>It had never really occurred to me you could use <code>None</code> (null) as a key to a dictionary before.
What this also meant is that <code>None</code> must be hashable as only hashable objects can be keys in a dictionary.
These objects include <code>strings</code>, <code>tuples</code>, <code>sets</code> but don&rsquo;t include <code>lists</code> as they are mutable and not
hashable.</p>
<details
  class="notice tip"
  open="false"
>
    <summary class="notice-title">Lists as keys?</summary>
  
  <p>Using a list as a key won&rsquo;t provide a consistent hash therefore you wouldn&rsquo;t be able
to find the value associated with that list. Again this is because lists are mutable
so their hash would change.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;a&#34;</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="nb">hash</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="o">---------------------------------------------------------------</span>
</span></span><span class="line"><span class="cl"><span class="ne">TypeError</span>                     <span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Cell</span> <span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">line</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="o">----&gt;</span> <span class="mi">1</span> <span class="nb">hash</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="ne">TypeError</span><span class="p">:</span> <span class="n">unhashable</span> <span class="nb">type</span><span class="p">:</span> <span class="s1">&#39;list&#39;</span>
</span></span></code></pre></div><p>In fact for this very reason you cannot even hash them using the builtin <code>hash</code> function in python.</p>

</details>

<h2 id="hash">Hash?</h2>
<p>If we do try to use the built-in <code>hash</code> function on <code>None</code> you will notice we do get a hash (int) as expected.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="nb">hash</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Out</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="mi">8783956518372</span>
</span></span></code></pre></div><blockquote>
<p>So yeah you can use <code>None</code> as a key in a dictionary.</p>
</blockquote>
<details
  class="notice warning"
  open="false"
>
    <summary class="notice-title">JSON Caveat</summary>
  
  <p>One thing to note is when transforming a dictionary into JSON. The <code>None</code> will become a string.
So when you convert it back from JSON to a python dictionary it will be something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">d</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;None&#34;</span><span class="p">:</span> <span class="s2">&#34;value&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># ...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</details>

]]></content:encoded>
    </item>
    
    <item>
      <title>TIL: About Conditional Gitconfigs</title>
      <link>https://haseebmajid.dev/posts/2022-11-12-til-about-conditional-gitconfigs/</link>
      <pubDate>Sat, 12 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-12-til-about-conditional-gitconfigs/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TIL you can have conditional sections in your &lt;code&gt;.gitconfig&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As some of you may know, I keep my &lt;a href=&#34;https://gitlab.com/hmajid2301/dotfiles&#34;&gt;dotfiles&lt;/a&gt; in a git repo.
The problem with this approach is that my email in my &lt;code&gt;.gitconfig&lt;/code&gt; is set to &lt;code&gt;hello@haseebmajid.dev&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Where my config looks something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[user]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;email&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;hello@haseebmajid.dev
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  name = Haseeb Majid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, when I am at work I need to use a different email to commit i.e. work email &lt;code&gt;haseeb@work.com&lt;/code&gt; not my personal
email. So I was wondering how could I do that; one way would be to change the file locally and just not commit it.
But of course, that is not ideal.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TIL you can have conditional sections in your <code>.gitconfig</code></strong></p>
<p>As some of you may know, I keep my <a href="https://gitlab.com/hmajid2301/dotfiles">dotfiles</a> in a git repo.
The problem with this approach is that my email in my <code>.gitconfig</code> is set to <code>hello@haseebmajid.dev</code>.</p>
<p>Where my config looks something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[user]</span>
</span></span><span class="line"><span class="cl">  <span class="na">email</span> <span class="o">=</span> <span class="s">hello@haseebmajid.dev
</span></span></span><span class="line"><span class="cl"><span class="s">  name = Haseeb Majid</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ...</span>
</span></span></code></pre></div><p>However, when I am at work I need to use a different email to commit i.e. work email <code>haseeb@work.com</code> not my personal
email. So I was wondering how could I do that; one way would be to change the file locally and just not commit it.
But of course, that is not ideal.</p>
<p>Then I discovered we can add other gitconfigs using the conditional <code>includeIf</code> clause. You can
read more about <a href="https://git-scm.com/docs/git-config#_conditional_includes">them here</a>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[user]</span>
</span></span><span class="line"><span class="cl">  <span class="na">email</span> <span class="o">=</span> <span class="s">hello@haseebmajid.dev
</span></span></span><span class="line"><span class="cl"><span class="s">  name = Haseeb Majid</span>
</span></span><span class="line"><span class="cl"><span class="k">[includeIf &#34;gitdir:/Users/&#34;]</span>
</span></span><span class="line"><span class="cl">  <span class="na">path</span> <span class="o">=</span> <span class="s">.gitconfig.mac</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ...</span>
</span></span></code></pre></div><p>I use a Mac at work and Linux at home so I can a basic check on folder structure i.e. <code>/home/</code> vs <code>/Users/</code>.
Then in the <code>.gitconfig.mac</code> we can do something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[user]</span>
</span></span><span class="line"><span class="cl">  <span class="na">email</span> <span class="o">=</span> <span class="s">haseeb@work.com</span>
</span></span></code></pre></div><p>This will replace the email with my work one when I commit when we run the <code>git</code> CLI command in a folder within <code>/Users/</code> folder.</p>
<details
  class="notice tip"
  open="true"
>
    <summary class="notice-title">Wild Card</summary>
  
  When we specify <code>/Users/</code> in the <code>gitdir</code> if clause it automatically treats it like <code>/Users/**</code>.
So any sub-directories within users also count.
</details>

<p>That&rsquo;s it! Now we can keep separate settings between work and home. We can also extend this to have different settings between
different OS&rsquo;s such as default editor.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>What is a TIL Post?</title>
      <link>https://haseebmajid.dev/posts/2022-11-11-what-is-a-til-post/</link>
      <pubDate>Fri, 11 Nov 2022 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2022-11-11-what-is-a-til-post/</guid>
      <description>&lt;h1 id=&#34;what-is-a-til-post&#34;&gt;What is a TIL post?&lt;/h1&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2022-11-11-what-is-a-til-post/images/til.jpg&#34;
        type=&#34;&#34;
        alt=&#34;TIL&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;TIL - Stands for today I learnt. These posts will be shorts summaries of something I learnt &amp;ldquo;today&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The TIL posts have a low barrier to entry and are a lot easier to write. Therefore they should encourage me
to post more often. In all my blog posts I try to post about things that I struggled to do. If I struggled
to implement a feature or build something. It shows that there wasn&amp;rsquo;t a tutorial or an easy example I could follow.
So then I usually decide to write my own, to make it easier for others. It also has a nice side effect of helping me remember the topic
better.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h1 id="what-is-a-til-post">What is a TIL post?</h1>
<p><img
        loading="lazy"
        src="/posts/2022-11-11-what-is-a-til-post/images/til.jpg"
        type=""
        alt="TIL"
        
      /></p>
<p>TIL - Stands for today I learnt. These posts will be shorts summaries of something I learnt &ldquo;today&rdquo;.</p>
<p>The TIL posts have a low barrier to entry and are a lot easier to write. Therefore they should encourage me
to post more often. In all my blog posts I try to post about things that I struggled to do. If I struggled
to implement a feature or build something. It shows that there wasn&rsquo;t a tutorial or an easy example I could follow.
So then I usually decide to write my own, to make it easier for others. It also has a nice side effect of helping me remember the topic
better.</p>
<p>Also, a TIL is a lot easier to write as they are a lot shorter. I cannot stress how important it is that they are shorter.
More seriously it also will hopefully force me to be more concise and try to write fewer words to convey what I mean.
These posts are also great for me, and I can reference them later if I forget something, which I definitely will.</p>
<details
  class="notice warning"
  open="true"
>
    <summary class="notice-title">Disclaimer</summary>
  
  However, most likely it will be something I learnt recently, as I often don&rsquo;t have the energy/time to post
the same day I learn something new 😅.
</details>

<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://betatim.github.io/posts/til-explained/">My Inspiration</a></li>
<li><a href="https://rabea.dev/til/gitconfig-with-conditionals">More Inspiration</a></li>
</ul>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
