<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>The Terminal Yard - vim</title>
    <subtitle>Writing about terminals and linux</subtitle>
    <link rel="self" type="application/atom+xml" href="https://blog.lazyfreax.dev/tags/vim/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://blog.lazyfreax.dev"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-02-17T00:00:00+00:00</updated>
    <id>https://blog.lazyfreax.dev/tags/vim/atom.xml</id>
    <entry xml:lang="en">
        <title>Custom Desktop Web Apps with Hyprland</title>
        <published>2026-02-17T00:00:00+00:00</published>
        <updated>2026-02-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              coko
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.lazyfreax.dev/blog/custom-desktop-web-apps-with-hyprland/"/>
        <id>https://blog.lazyfreax.dev/blog/custom-desktop-web-apps-with-hyprland/</id>
        
        <content type="html" xml:base="https://blog.lazyfreax.dev/blog/custom-desktop-web-apps-with-hyprland/">&lt;p&gt;The reason I use Linux is because I like to configure my system to be exactly how I want it.&lt;&#x2F;p&gt;
&lt;p&gt;This is why I went with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;archlinux.org&#x2F;&quot;&gt;Arch Linux&lt;&#x2F;a&gt; &lt;em&gt;(btw)&lt;&#x2F;em&gt;. Arch may not be for everyone but when you are picky like me when it comes to what software goes on your machine, it&#x27;s simply the perfect choice.&lt;&#x2F;p&gt;
&lt;p&gt;On top of that, I use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hypr.land&#x2F;&quot;&gt;Hyprland&lt;&#x2F;a&gt; as my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tiling_window_manager&quot;&gt;tiling window manager&lt;&#x2F;a&gt; &lt;em&gt;(it&#x27;s an hybrid window manager to be more accurate, but you get the idea)&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;While I recognize the mouse to be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=yJDv-zdhzMY&quot;&gt;a truly magnificent invention&lt;&#x2F;a&gt;, the less I have to use it, the better I feel.
I am a keyboard maximalist, I don&#x27;t want my hands to ever leave the keyboard so a tiling window manager fits my workflow the best.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;predefined-workspaces&quot;&gt;Predefined Workspaces&lt;a class=&quot;post-anchor&quot; href=&quot;#predefined-workspaces&quot; aria-label=&quot;Anchor link for: predefined-workspaces&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The way I setup my environment is that I have ten workspaces and each of them gets assigned specific applications:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;freetubeapp.io&#x2F;&quot;&gt;FreeTube&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Web browsers (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;librewolf.net&#x2F;&quot;&gt;Librewolf&lt;&#x2F;a&gt; &#x2F; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ungoogled-software&#x2F;ungoogled-chromium&quot;&gt;Chromium&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;qutebrowser.org&#x2F;&quot;&gt;qutebrowser&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Terminal (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sw.kovidgoyal.net&#x2F;kitty&#x2F;&quot;&gt;kitty&lt;&#x2F;a&gt; &#x2F; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ghostty.org&#x2F;&quot;&gt;ghostty&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Email client&lt;&#x2F;li&gt;
&lt;li&gt;Chat apps (Discord, Signal, Teams, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Office (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.onlyoffice.com&#x2F;&quot;&gt;OnlyOffice&lt;&#x2F;a&gt; &#x2F; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.libreoffice.org&#x2F;&quot;&gt;LibreOffice&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Video games &amp;amp; graphics (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gimp.org&#x2F;&quot;&gt;Gimp&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Remote desktop (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;remmina.org&#x2F;&quot;&gt;Remmina&lt;&#x2F;a&gt;) &amp;amp; Virtual Machines&lt;&#x2F;li&gt;
&lt;li&gt;Misc &amp;amp; Tools (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.qbittorrent.org&#x2F;&quot;&gt;qBittorent&lt;&#x2F;a&gt;, Spotify, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Random stuff &lt;em&gt;(I usually bind it to my second monitor)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The great thing about this is that I don&#x27;t have to think about where my windows are. Switching to a specific application is built into my muscle memory.
If I want to search on the web, I press &lt;kbd&gt;SUPER+2&lt;&#x2F;kbd&gt;. Need to read an email? &lt;kbd&gt;SUPER+4&lt;&#x2F;kbd&gt;, etc.
It&#x27;s fast, there is no mental overhead, I love it.&lt;&#x2F;p&gt;
&lt;p&gt;When you spend 8+ hours a day on a computer, the mental fatigue of having to &lt;kbd&gt;Alt+Tab&lt;&#x2F;kbd&gt; and manually search through your windows really builds up.&lt;&#x2F;p&gt;
&lt;p&gt;The Workspace config is available on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coko7&#x2F;.dotfiles&#x2F;blob&#x2F;main&#x2F;.config&#x2F;hypr&#x2F;window_rules_workspaces.conf&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;creating-custom-desktop-web-apps&quot;&gt;Creating custom Desktop Web apps&lt;a class=&quot;post-anchor&quot; href=&quot;#creating-custom-desktop-web-apps&quot; aria-label=&quot;Anchor link for: creating-custom-desktop-web-apps&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;OK, now you have a basic idea of what my workflow looks like. So why do I need desktop web apps?
And by that, I mean: Web apps that I can launch like any other application.&lt;&#x2F;p&gt;
&lt;p&gt;Well, as you know, I like to bind applications to workspaces. But sometimes, I have to use applications or services that are not available on desktop.
I could simply stick to using them in my web browser, and, that&#x27;s what I do for some of them. But, when I find myself using a web app a lot, I want to have it available on my desktop directly.&lt;&#x2F;p&gt;
&lt;p&gt;To create the desktop web app, we need three things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a desktop entry&lt;&#x2F;li&gt;
&lt;li&gt;an executable script&lt;&#x2F;li&gt;
&lt;li&gt;some Hyprland rules&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In this article, I will walk you through the process of creating a desktop web app for Outlook.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;desktop-entry&quot;&gt;Desktop entry&lt;a class=&quot;post-anchor&quot; href=&quot;#desktop-entry&quot; aria-label=&quot;Anchor link for: desktop-entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;First, we need to create a custom &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Desktop_entries&quot;&gt;desktop entry&lt;&#x2F;a&gt; (&lt;code&gt;*.desktop&lt;&#x2F;code&gt; files):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;desktop&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;[Desktop Entry]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Outlook&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Comment&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Read your emails&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;GenericName&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Work Email Client&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Keywords&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Work;Email;Outlook&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #CDD6F412;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Exec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;home&#x2F;coko&#x2F;.config&#x2F;local&#x2F;bin-sh&#x2F;work&#x2F;chromium-outlook.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Icon&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;outlook&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Terminal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;Application&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;StartupNotify&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;Categories&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;font-weight: bold;&quot;&gt;Network&lt;&#x2F;span&gt;&lt;span&gt;;Email;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above snippet is a desktop file that I placed in my &lt;code&gt;~&#x2F;.config&#x2F;local&#x2F;share&#x2F;applications&#x2F;&lt;&#x2F;code&gt; directory.&lt;&#x2F;p&gt;
&lt;p&gt;When I press &lt;kbd&gt;SUPER+R&lt;&#x2F;kbd&gt;, it starts my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Category:Application_launchers&quot;&gt;application launcher&lt;&#x2F;a&gt; which automatically picks up this entry and makes it available to me.
I use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;davatorium&#x2F;rofi&quot;&gt;rofi&lt;&#x2F;a&gt; as my application launcher but if you use a different one, it should behave similarly.&lt;&#x2F;p&gt;
&lt;p&gt;You can specify a lot of things in a desktop entry, but what we want to focus on is the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Exec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&#x2F;home&#x2F;coko&#x2F;.config&#x2F;local&#x2F;bin-sh&#x2F;work&#x2F;chromium-outlook.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;Exec&lt;&#x2F;code&gt; value is the action that will be triggered when you launch the application. In this case, it is a custom bash script named &lt;code&gt;chromium-outlook.sh&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Never heard of bash? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learnxinyminutes.com&#x2F;bash&#x2F;&quot;&gt;Learn it in Y minutes!&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;executable-script&quot;&gt;Executable script&lt;a class=&quot;post-anchor&quot; href=&quot;#executable-script&quot; aria-label=&quot;Anchor link for: executable-script&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Now, let&#x27;s look into the bash script from the desktop entry:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;DATA_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$XDG_CONFIG_HOME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&#x2F;chromium-work-outlook&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;chromium-nerd-app.sh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;https:&#x2F;&#x2F;outlook.office.com&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$DATA_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It&#x27;s tiny, only two lines without the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Shebang_(Unix)&quot;&gt;Shebang&lt;&#x2F;a&gt;.
First, I define the data directory for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ungoogled-software&#x2F;ungoogled-chromium&quot;&gt;Chromium&lt;&#x2F;a&gt;, which is the web browser I use for my custom desktop web apps.
This is mostly for isolation purposes, the actual line we want to have a look at is &lt;strong&gt;line 4&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;chromium-nerd-app.sh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;https:&#x2F;&#x2F;outlook.office.com&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$DATA_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It calls another script (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coko7&#x2F;.dotfiles&#x2F;blob&#x2F;main&#x2F;.config&#x2F;local&#x2F;bin-sh&#x2F;global&#x2F;chromium-nerd-app.sh&quot;&gt;&lt;code&gt;chromium-nerd-app.sh&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;) with two arguments (a URL and the data dir we defined).
Let&#x27;s checkout this new bash script:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;APP_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -z&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$APP_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; ]] &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;APP_NAME required!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;DATA_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;$2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -z&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$DATA_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; ]] &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;DATA_DIR required!&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;VIMIUM_EXT_ID&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;#39;dbepggeogbaibhgnhhndojpepiihcmeb&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;VIMIUM_VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;#39;2.3.1_0&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;CHROMIUM_EXT_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$XDG_CONFIG_HOME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&#x2F;chromium&#x2F;Default&#x2F;Extensions&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;VIMIUM_EXT_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$CHROMIUM_EXT_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;$VIMIUM_EXT_ID&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;$VIMIUM_VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;&#x2F;usr&#x2F;bin&#x2F;chromium&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    --app=&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$APP_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    --disable-features=WaylandWpColorManagerV1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    --user-data-dir=&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$DATA_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    --load-extension=&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$VIMIUM_EXT_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Okay, this one looks a little more daunting, but it&#x27;s not that complicated actually.&lt;&#x2F;p&gt;
&lt;p&gt;The first few lines simply ensure that the script is called with two arguments (the app URL and the data directory).&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s skip ahead to &lt;strong&gt;lines 9-12&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VIMIUM_EXT_ID&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;#39;dbepggeogbaibhgnhhndojpepiihcmeb&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VIMIUM_VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;#39;2.3.1_0&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CHROMIUM_EXT_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$XDG_CONFIG_HOME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&#x2F;chromium&#x2F;Default&#x2F;Extensions&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VIMIUM_EXT_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$CHROMIUM_EXT_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;$VIMIUM_EXT_ID&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;$VIMIUM_VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This part is optional &lt;em&gt;&lt;strong&gt;but it&#x27;s my favorite part&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;.
If you are familiar with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vimium.github.io&#x2F;&quot;&gt;Vimium&lt;&#x2F;a&gt;, you already know what&#x27;s coming.
But, basically: Vimium is a browser extension that brings vim keybindings in your web browser.
Some think it&#x27;s overkill, I cannot live without it.&lt;&#x2F;p&gt;
&lt;p&gt;These four lines define the path to the Vimium extension on my system.
The same could have been achieved with a single line but this is more readable.&lt;&#x2F;p&gt;
&lt;p&gt;Then, finally, the heart of the script &lt;em&gt;(where the magic happens ✨)&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;&#x2F;usr&#x2F;bin&#x2F;chromium&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    --app=&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$APP_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    --disable-features=WaylandWpColorManagerV1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    --user-data-dir=&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$DATA_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    --load-extension=&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;$VIMIUM_EXT_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s break it down line by line:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Launch the Chromium binary: &lt;code&gt;&#x2F;usr&#x2F;bin&#x2F;chromium&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--app=&amp;lt;URL&amp;gt;&lt;&#x2F;code&gt; tells Chromium to start in a &lt;strong&gt;application&lt;&#x2F;strong&gt; mode, it will hide menu bars, disable extensions, etc.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--disable-features=WaylandWpColorManagerV1&lt;&#x2F;code&gt; is for fixing some color issues on Wayland (to be honest, I don&#x27;t remember why it&#x27;s there but there must be a reason)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--user-data-dir=&quot;$DATA_DIR&quot;&lt;&#x2F;code&gt; tells Chromium to use the data directory passed as second argument &lt;code&gt;$2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--load-extension=&quot;$VIMIUM_EXT_PATH&quot;&lt;&#x2F;code&gt; instructs Chromium to specifically load the Vimium extension&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;And that&#x27;s it!&lt;&#x2F;p&gt;
&lt;p&gt;With this, whenever I launch Outlook from my app launcher, it will open a custom instance of Chromium with Outlook opened. It looks and feels like
a desktop app but it is actually a disguised Chromium browser.&lt;&#x2F;p&gt;
&lt;p&gt;We are almost done, but there is still one important thing left: &lt;strong&gt;binding the app to a Hyprland workspace&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hyprland-rules&quot;&gt;Hyprland rules&lt;a class=&quot;post-anchor&quot; href=&quot;#hyprland-rules&quot; aria-label=&quot;Anchor link for: hyprland-rules&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you remember my workspace setup, I want my email client to open on workspace 4.
To do this, I need to define some &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.hypr.land&#x2F;Configuring&#x2F;Window-Rules&#x2F;&quot;&gt;window rules&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Since my config is quite big, I have decided to split it into multiple files and I keep workspace-related window rules in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coko7&#x2F;.dotfiles&#x2F;blob&#x2F;main&#x2F;.config&#x2F;hypr&#x2F;window_rules_workspaces.conf&quot;&gt;&lt;code&gt;window_rules_workspace.conf&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt;windowrule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; workspace 4, match:class ^(chrome-outlook.office.com__-Default)$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt;windowrule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; match:class ^(chrome-outlook.office.com__-Default)$, tile on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hyprland configuration is rather easy to understand even if it&#x27;s your first time seeing it:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Assign Outlook to &lt;strong&gt;workspace 4&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Force the Outlook window to be tiled instead of floating&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In this case, the &lt;code&gt;^(chrome-outlook.office.com__-Default)$&lt;&#x2F;code&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Regular_expression&quot;&gt;regex&lt;&#x2F;a&gt; matches the Outlook window.
Okay, sure... But where did I find weird-looking class name?&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s Hyprland&#x27;s strongest suite in my opinion, it comes with a bunch of tools that expose metadata about desktop objects (windows, monitors, devices, etc.).
Here, the command I use to get the class name for Outlook is the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;hyprctl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; clients -j&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; jq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;#39;.[].class&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;More nonsense commands 😡 !!??&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Calm down, I will explain everything:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hyprctl clients -j&lt;&#x2F;code&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hyprctl&lt;&#x2F;code&gt; is the main Hyprland command line tool to query desktop objects&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;clients&lt;&#x2F;code&gt; is a subcommand of &lt;code&gt;hyprctl&lt;&#x2F;code&gt; that uses the Hyprland API to find the list of clients (opened windows&#x2F;applications)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-j&lt;&#x2F;code&gt; tells Hyprland to format the output as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;JSON&quot;&gt;JSON&lt;&#x2F;a&gt; &lt;em&gt;(that&#x27;s why I love Hyprland)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;jq &#x27;.[].class&#x27;&lt;&#x2F;code&gt; relies on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jqlang&#x2F;jq&quot;&gt;jq&lt;&#x2F;a&gt; to process the JSON output from Hyprland and format it to only show individual class names.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When I run this on my system, this is what I get:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellsession&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; hyprctl clients -j &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; jq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;#39;.[].class&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;librewolf&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;chrome-outlook.office.com__-Default&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;kitty&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Spot anything familiar? I don&#x27;t know about you but the second class &lt;code&gt;chrome-outlook.office.com__-Default&lt;&#x2F;code&gt; sure sounds like it could be our Outlook window.&lt;&#x2F;p&gt;
&lt;p&gt;And that&#x27;s it! Now when I launch Outlook, it will always be opened on workspace 4. Easy enough, right?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;post-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;It may seem like I have to do a lot of work to turn a simple website into a desktop application. But, in reality, all I have to do is create the desktop entry and the Hyprland rule.
And creating these takes one or two minutes.
Most of the heavy lifting is performed by the &lt;code&gt;chromium-nerd-app.sh&lt;&#x2F;code&gt; script.&lt;&#x2F;p&gt;
&lt;p&gt;I hope you liked this article and learned some neat things. I had a lot of fun writing it!
All the configuration and scripts shown here can be found on my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coko7&#x2F;.dotfiles&quot;&gt;GitHub&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coko7&#x2F;.dotfiles&#x2F;tree&#x2F;main&#x2F;.config&#x2F;hypr&quot;&gt;Hyprland files&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coko7&#x2F;.dotfiles&#x2F;blob&#x2F;main&#x2F;.config&#x2F;local&#x2F;bin-sh&#x2F;global&#x2F;chromium-nerd-app.sh&quot;&gt;chromium-nerd-app.sh script&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you have any question or feedback, feel free to email me at &lt;a href=&quot;mailto:contact@coko7.fr&quot;&gt;contact@coko7.fr&lt;&#x2F;a&gt;. Please consider sharing this around if you found it helpful &lt;em&gt;(or even if it was not helpful)&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Alright, I am done with my rambling. Bye bye 👋&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;:wqa&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Vim Keymap For Markdown Links</title>
        <published>2026-02-05T00:00:00+00:00</published>
        <updated>2026-02-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              coko
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.lazyfreax.dev/blog/vim-keymap-for-markdown-links/"/>
        <id>https://blog.lazyfreax.dev/blog/vim-keymap-for-markdown-links/</id>
        
        <content type="html" xml:base="https://blog.lazyfreax.dev/blog/vim-keymap-for-markdown-links/">&lt;p&gt;I work with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Markdown&quot;&gt;Markdown&lt;&#x2F;a&gt; a lot. I use it for note-taking, documenting projects, creating personal wikis &lt;em&gt;(and a world-building wiki!)&lt;&#x2F;em&gt;, etc.
And most recently, I have started this blog so I use it even more than before.&lt;&#x2F;p&gt;
&lt;p&gt;Whenever I edit text in Markdown, I often find myself adding links here and there.
Since I also use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;neovim.io&#x2F;&quot;&gt;Neovim&lt;&#x2F;a&gt; as my primary text&#x2F;code editor, I can easily add links to text elements using minimal vim motions.&lt;&#x2F;p&gt;
&lt;p&gt;It works well and it literally takes less than a second to do that.
But when I have to add dozens of links, it starts feeling a bit repetitive.&lt;&#x2F;p&gt;
&lt;p&gt;The great thing about Vim&#x2F;Neovim: &lt;strong&gt;You can configure your editor to do EXACTLY what you want&lt;&#x2F;strong&gt;.
So, I thought: &quot;why not create a custom keymap for that?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;What I wanted:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Copy some URL to my system clipboard&lt;&#x2F;li&gt;
&lt;li&gt;Select some text in Neovim&lt;&#x2F;li&gt;
&lt;li&gt;Type &lt;kbd&gt;&amp;lt;leader&amp;gt;l&lt;&#x2F;kbd&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Have Neovim convert the selection to a markdown link &lt;code&gt;[text](link)&lt;&#x2F;code&gt;, where:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;text&lt;&#x2F;code&gt; is the selected text&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;link&lt;&#x2F;code&gt; is the URL I copied to my system clipboard (&lt;code&gt;+&lt;&#x2F;code&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vimhelp.org&#x2F;change.txt.html#registers&quot;&gt;register&lt;&#x2F;a&gt; in Vim)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;the-keymap&quot;&gt;The keymap&lt;a class=&quot;post-anchor&quot; href=&quot;#the-keymap&quot; aria-label=&quot;Anchor link for: the-keymap&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Here&#x27;s the keymap I have added to my Neovim config:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;lua&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;vim.keymap.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    &amp;quot;x&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    &amp;quot;&amp;lt;leader&amp;gt;l&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    &amp;quot;&amp;lt;Esc&amp;gt;`&amp;lt;i[&amp;lt;Esc&amp;gt;`&amp;gt;la](&amp;lt;C-r&amp;gt;+)&amp;lt;Esc&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;    { desc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;Apply markdown [L]ink on current selection&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To define a new keymap, we call &lt;code&gt;vim.keymap.set(...)&lt;&#x2F;code&gt; and give it some arguments:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The first argument &lt;code&gt;&quot;x&quot;&lt;&#x2F;code&gt; tells Neovim to only enable the keymap in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vimhelp.org&#x2F;visual.txt.html#Visual-mode&quot;&gt;Visual mode&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The second argument &lt;code&gt;&quot;&amp;lt;leader&amp;gt;l&quot;&lt;&#x2F;code&gt; is the actual keybinding.
In this case, &lt;code&gt;&amp;lt;leader&amp;gt;&lt;&#x2F;code&gt; corresponds to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vimhelp.org&#x2F;map.txt.html#%3CLeader%3E&quot;&gt;Leader&lt;&#x2F;a&gt; key which I set to &lt;kbd&gt;Space&lt;&#x2F;kbd&gt; in my config.
So, when I type &lt;kbd&gt;Space+l&lt;&#x2F;kbd&gt; it will trigger this keymap&lt;&#x2F;li&gt;
&lt;li&gt;The third argument is the sequence of motions to execute when the keymap is invoked&lt;&#x2F;li&gt;
&lt;li&gt;Finally, we define a description for the keymap&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The thing we want to have a look at is the sequence of motions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Esc&amp;gt;`&amp;lt;i[&amp;lt;Esc&amp;gt;`&amp;gt;la](&amp;lt;C-r&amp;gt;+)&amp;lt;Esc&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So, let&#x27;s break it down:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;First, we use &lt;code&gt;&amp;lt;Esc&amp;gt;&lt;&#x2F;code&gt; to switch to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vimhelp.org&#x2F;intro.txt.html#Normal-mode&quot;&gt;Normal mode&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Then, we move the cursor to the start of the previous visual selection with &lt;code&gt;`&amp;lt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;After that, &lt;code&gt;i[&amp;lt;Esc&amp;gt;&lt;&#x2F;code&gt; lets us switch to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vimhelp.org&#x2F;insert.txt.html#Insert-mode&quot;&gt;Insert mode&lt;&#x2F;a&gt;, put an opening square bracket &#x27;[&#x27;, before going back to Normal mode once again with &lt;kbd&gt;Escape&lt;&#x2F;kbd&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Then, this time, we go to the end of the last visual selection with &lt;code&gt; `&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;We use &lt;code&gt;l&lt;&#x2F;code&gt; to move the cursor one unit to the right
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;This is needed because the opening square bracket we inserted earlier has shifted the last visual selection. If we did not do that, we would be one character off&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;We proceed to append the &#x27;]&#x27; and &#x27;(&#x27; characters with &lt;code&gt;a](&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;While still in Insert mode, we use &lt;code&gt;&amp;lt;C-r&amp;gt;+&lt;&#x2F;code&gt; to paste the content of the &lt;code&gt;+&lt;&#x2F;code&gt; register, which is the system clipboard (where our URL is stored)
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vimhelp.org&#x2F;cmdline.txt.html#c_%3CC-R%3E&quot;&gt;&lt;code&gt;:help c_&amp;lt;C-R&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to learn more&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Finally, we insert the closing parenthesis and go back to Normal mode with &lt;code&gt;)&amp;lt;Esc&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That was not so bad, was it?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;complementary-keymap-for-normal-mode&quot;&gt;Complementary keymap for Normal mode&lt;a class=&quot;post-anchor&quot; href=&quot;#complementary-keymap-for-normal-mode&quot; aria-label=&quot;Anchor link for: complementary-keymap-for-normal-mode&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The previous keymap works great for any visual selection.
It allows you to select some text and apply a markdown link to it.&lt;&#x2F;p&gt;
&lt;p&gt;But what if you only want to add a link to a single word?
Do we really want to bother with a visual selection for that?
I don&#x27;t think so. Time to create a second keymap:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;lua&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;vim.keymap.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    &amp;quot;n&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    &amp;quot;&amp;lt;leader&amp;gt;l&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;    &amp;#39;&amp;quot;9ciw[]&amp;lt;Esc&amp;gt;&amp;quot;9Pf]a(&amp;lt;C-r&amp;gt;+)&amp;lt;Esc&amp;gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;    { desc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;Apply markdown [L]ink on current word&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #7F849C;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It looks very similar to our first keymap with a few tweaks here and there.
The first difference we notice is the first argument &lt;code&gt;&quot;n&quot;&lt;&#x2F;code&gt; which tells Neovim to enable this keymap in Normal mode only.
The key binding has not changed, we still want to use &lt;code&gt;&amp;lt;leader&amp;gt;l&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This means both keymaps use the same key binding, the only difference is the Vim mode you are in.
This is what determines which keymap to call.&lt;&#x2F;p&gt;
&lt;p&gt;Okay, let&#x27;s go over the motions now:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;quot;9ciw[]&amp;lt;Esc&amp;gt;&amp;quot;9Pf]a(&amp;lt;C-r&amp;gt;+)&amp;lt;Esc&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you pay a closer look to the last part, you will notice that it is the same as before:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a](&amp;lt;C-r&amp;gt;+)&amp;lt;Esc&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So the only motions that differ are the ones prior to inserting the closing square bracket &#x27;]&#x27;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;quot;9ciw[]&amp;lt;Esc&amp;gt;&amp;quot;9Pf]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;New motions to break down. &lt;strong&gt;Exciting!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Let&#x27;s start with &lt;code&gt;&quot;9ciw&lt;&#x2F;code&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&quot;9&lt;&#x2F;code&gt; tells Neovim we want to operate against the &lt;code&gt;9&lt;&#x2F;code&gt; register.
There is no reason for using this specific register, you may use another one if you prefer.
I picked this one arbitrarily.
Just make sure not to pick register &lt;code&gt;+&lt;&#x2F;code&gt; because our URL is stored in there&lt;&#x2F;li&gt;
&lt;li&gt;Then, &lt;code&gt;ciw&lt;&#x2F;code&gt; will replace &lt;strong&gt;inside&lt;&#x2F;strong&gt; the current word and store the deleted text to register &lt;code&gt;9&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The previous motion put us in Insert mode, we can now insert square brackets &lt;code&gt;[]&lt;&#x2F;code&gt; and go back to Normal mode with &lt;kbd&gt;Escape&lt;&#x2F;kbd&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The awaited return of register &lt;code&gt;9&lt;&#x2F;code&gt;! We use &lt;code&gt;&quot;9P&lt;&#x2F;code&gt; to paste our deleted word to the &lt;strong&gt;left&lt;&#x2F;strong&gt; of the cursor
&lt;ul&gt;
&lt;li&gt;Had we use &lt;code&gt;p&lt;&#x2F;code&gt; instead of &lt;code&gt;P&lt;&#x2F;code&gt;, and the text would have been pasted outside of the square brackets &lt;em&gt;(which is not we want!)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Finally, we move the cursor on the next closing square bracket with &lt;code&gt;f]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Then, it&#x27;s just the last part which is exactly the same as before: &lt;code&gt;a](&amp;lt;C-r&amp;gt;+)&amp;lt;Esc&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So now, if we move the cursor on any word in Normal mode and hit &lt;code&gt;&amp;lt;leader&amp;gt;l&lt;&#x2F;code&gt;, it will automatically format it as a Markdown link. Pretty cool!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;post-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Okay, this might seem like a lot just to save a few milliseconds here and there. Was it really worth it?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;YES!&lt;&#x2F;strong&gt;
&lt;em&gt;(I have used &lt;code&gt;&amp;lt;leader&amp;gt;l&lt;&#x2F;code&gt; a lot to write this article already)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Maybe it will take a lot of time before this keybind actually pays off.
But overall, I am having so much fun just trying to solve these kind of problems in Neovim.
This is what makes using Neovim so enjoyable to me.&lt;&#x2F;p&gt;
&lt;p&gt;I think having fun is the best remedy to avoid burnouts.
For me, I get my fun from using Neovim and the terminal, customizing my environment to be exactly how I want it.
It&#x27;s probably different for you but I hope you get your fun from somewhere else at least.&lt;&#x2F;p&gt;
&lt;p&gt;I hope I made you learn some neat Vim tricks!
If you liked this article, please consider sharing it around to any other vim addicts.
If you want to take a peek at my Neovim config, I keep it on GitHub: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Coko7&#x2F;neovim-config&quot;&gt;coko7&#x2F;neovim-config&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Feel free to check out my other articles too!
Until next time 👋&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;:wqa&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
