<?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>Tools on Andrei Mahalean&#39;s Weblog</title>
    <link>https://blog.maha.nz/tags/tools/</link>
    <description>Recent content in Tools on Andrei Mahalean&#39;s Weblog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-US</language>
    <copyright>Andrei Mahalean (CC BY 4.0)</copyright>
    <lastBuildDate>Fri, 02 Aug 2024 00:00:00 +1200</lastBuildDate>
    <atom:link href="https://blog.maha.nz/tags/tools/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Open URLs from WSL in your default browser</title>
      <link>https://blog.maha.nz/posts/pr-lazygit-wsl/</link>
      <pubDate>Fri, 02 Aug 2024 00:00:00 +1200</pubDate>
      <guid>https://blog.maha.nz/posts/pr-lazygit-wsl/</guid>
      <description>&lt;p&gt;When you prefer a terminal based workflow, and you want a bit more than the standard git cli (or any aliases you may have setup to make life easier), &lt;a href=&#34;https://github.com/jesseduffield/lazygit&#34;&gt;lazygit&lt;/a&gt; is hands down my favorite tool to work with. Please read the &lt;a href=&#34;https://github.com/jesseduffield/lazygit?tab=readme-ov-file#elevator-pitch&#34;&gt;elevator pitch&lt;/a&gt;, then give it a try.&lt;/p&gt;&#xA;&lt;p&gt;However, there is one feature that did not seem to work for me in WSL, until today that is.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problem&#34;&gt;The Problem&lt;/h2&gt;&#xA;&lt;p&gt;When using lazygit in WSL, the &lt;code&gt;create pull request&lt;/code&gt; feature (shortcut &lt;code&gt;o&lt;/code&gt; when on branch view) typically fails because WSL doesn&amp;rsquo;t have direct access to graphical applications. The &lt;code&gt;xdg-open&lt;/code&gt; command, which lazygit uses to open URLs, doesn&amp;rsquo;t work out of the box in WSL.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>When you prefer a terminal based workflow, and you want a bit more than the standard git cli (or any aliases you may have setup to make life easier), <a href="https://github.com/jesseduffield/lazygit">lazygit</a> is hands down my favorite tool to work with. Please read the <a href="https://github.com/jesseduffield/lazygit?tab=readme-ov-file#elevator-pitch">elevator pitch</a>, then give it a try.</p>
<p>However, there is one feature that did not seem to work for me in WSL, until today that is.</p>
<h2 id="the-problem">The Problem</h2>
<p>When using lazygit in WSL, the <code>create pull request</code> feature (shortcut <code>o</code> when on branch view) typically fails because WSL doesn&rsquo;t have direct access to graphical applications. The <code>xdg-open</code> command, which lazygit uses to open URLs, doesn&rsquo;t work out of the box in WSL.</p>
<h2 id="the-solution">The Solution</h2>
<p>We&rsquo;ll create a custom script that intercepts <code>xdg-open</code> calls and redirects them to the Windows host system. This allows us to open pull requests in the default Windows browser directly from lazygit.</p>
<h2 id="implementation">Implementation</h2>
<h3 id="step-1-create-the-wsl-open-script">Step 1: Create the WSL-Open Script</h3>
<p>First, we&rsquo;ll create a script that acts as a bridge between WSL and Windows:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo hx /usr/local/bin/wsl-open</span></span></code></pre></div><p>Add the following content:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">url</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Don&#39;t convert slashes for http/https URLs</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$url</span><span class="s2">&#34;</span> <span class="o">==</span> http* <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># For web URLs, use the original URL without modification</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Just escape single quotes for PowerShell</span>
</span></span><span class="line"><span class="cl">    <span class="nv">escaped_url</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$url</span><span class="s2">&#34;</span> <span class="p">|</span> sed <span class="s2">&#34;s/&#39;/&#39;&#39;/g&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">    powershell.exe -c <span class="s2">&#34;Start-Process &#39;</span><span class="nv">$escaped_url</span><span class="s2">&#39;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># For file paths, convert to Windows format</span>
</span></span><span class="line"><span class="cl">    <span class="nv">winpath</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$url</span><span class="s2">&#34;</span> <span class="p">|</span> sed <span class="s1">&#39;s/\//\\/g&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">    <span class="nv">escaped_url</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$winpath</span><span class="s2">&#34;</span> <span class="p">|</span> sed <span class="s2">&#34;s/&#39;/&#39;&#39;/g&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">    powershell.exe -c <span class="s2">&#34;Start-Process &#39;</span><span class="nv">$escaped_url</span><span class="s2">&#39;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div><p>Remember to make the script executable:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo chmod +x /usr/local/bin/wsl-open</span></span></code></pre></div><h3 id="step-2-configure-xdg-mime">Step 2: Configure XDG-MIME</h3>
<p>XDG-MIME is part of the XDG (X Desktop Group) standards, which are a set of freedesktop.org specifications for Unix-like operating systems, particularly Linux desktop environments. It is a command line tool for querying information about file type handling and adding descriptions for new file types.</p>
<p>Let&rsquo;s set <code>wsl-open</code>, the script we created in the previous step, as the default handler for HTTP(S) URLs:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">xdg-mime default wsl-open.desktop x-scheme-handler/http
</span></span><span class="line"><span class="cl">xdg-mime default wsl-open.desktop x-scheme-handler/https</span></span></code></pre></div><h3 id="step-3-create-a-desktop-entry">Step 3: Create a Desktop Entry</h3>
<p>Create a <code>.desktop</code> file for our <code>wsl-open</code> script:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo hx /usr/share/applications/wsl-open.desktop</span></span></code></pre></div><p>Add the following content, notice that we are using a placeholder <code>%u</code> for our URL which will be passed to the script when the desktop file is executed:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">[Desktop Entry]
</span></span><span class="line"><span class="cl">Name=WSL Open
</span></span><span class="line"><span class="cl">Exec=/usr/local/bin/wsl-open %u
</span></span><span class="line"><span class="cl">Type=Application
</span></span><span class="line"><span class="cl">Terminal=false
</span></span><span class="line"><span class="cl">MimeType=x-scheme-handler/http;x-scheme-handler/https;</span></span></code></pre></div><h3 id="step-4-update-xdg-settings">Step 4: Update XDG Settings</h3>
<p>Set <code>wsl-open</code> as the default web browser for <code>xdg-open</code>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">xdg-settings <span class="nb">set</span> default-web-browser wsl-open.desktop</span></span></code></pre></div><h3 id="step-5-configure-environment-variables">Step 5: Configure Environment Variables</h3>
<p>Add the following to your <code>~/.bashrc</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">BROWSER</span><span class="o">=</span>/usr/local/bin/wsl-open</span></span></code></pre></div><p>The line sets the default browser for the WSL environment to your custom wsl-open script. This ensures that when a program in WSL tries to open a URL, it uses your script, which in turn passes the URL to the Windows host system.</p>
<p>Run <code>source ~/.bashrc</code> to apply changes.</p>
<h2 id="testing-the-setup">Testing the Setup</h2>
<p>To test, run:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">xdg-open <span class="s2">&#34;https://github.com/&#34;</span></span></span></code></pre></div><p>This should open the URL in your default Windows browser.</p>
<h2 id="integration-with-lazygit">Integration with Lazygit</h2>
<p>With this setup in place, lazygit&rsquo;s &lsquo;open pull request&rsquo; feature should now work seamlessly. When you select the option to open a pull request, lazygit will use <code>xdg-open</code>, which in turn calls our <code>wsl-open</code> script, opening the pull request URL in your Windows browser.</p>
<h2 id="conclusion">Conclusion</h2>
<p>This solution bridges the gap between WSL and Windows, allowing for a small productivity gain when working with Git and pull requests. It&rsquo;s particularly useful for developers who prefer terminal-based Git clients but still need the ability to quickly review and manage pull requests in a browser.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
