<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.00">
  <channel>
       <title>Morgan CUGERONE&#39;s latest articles</title>
       <link><![CDATA[https://morgan.cugerone.com]]></link>
       <description>Frontend development, web accessibility, inclusive design, productivity...</description>
    <item>
       <title>Today I learned: How to use throw and try/catch blocks in combination with setTimeout</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-use-settimeout-throw-and-try-catch-blocks/</link>
       <description>&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;You should beware when using &lt;code&gt;setTimeout&lt;/code&gt; together with &lt;code&gt;throw&lt;/code&gt; and
&lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt; block.&lt;/p&gt;
&lt;p&gt;At first sight you may think that the below code is just fine and that it will
fail gracefully and proceed with the fallback plan.&lt;/p&gt;
&lt;p&gt;Well, not quite.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;
function willErrorBeCaught() {
  try {
    setTimeout(function callbackFunction() {
      throw new Error(&#39;There was a problem&#39;);
    }, 3000);
  } catch (error) {
    console.warn(&#39;There was a problem&#39;);
    
    // Placeholder for fallback implementation
  }
}

willErrorBeCaught();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code produces an &amp;quot;&lt;strong&gt;Uncaught Error: There was a problem&lt;/strong&gt;&amp;quot;.&lt;/p&gt;
&lt;p&gt;The reason is that, by the time the &lt;code&gt;callbackFunction&lt;/code&gt; function is executed,
i.e. after at least 3 seconds, the &lt;code&gt;willErrorBeCaught&lt;/code&gt; function will have
already been removed from the call stack. This makes its &lt;code&gt;catch&lt;/code&gt; block code
unreachable, and thus, the error uncaught.&lt;/p&gt;
&lt;p&gt;This is indeed stated in the MDN docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Execution of the current function will stop (the statements after throw won&#39;t
be executed), and control will be passed to the first catch block in the call
stack. If no catch block exists among caller functions, the program will
terminate.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;The solution is rather simple. Shift the &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt; block into the
&lt;code&gt;callbackFunction&lt;/code&gt; function, as show in the code snippet below.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;
function willErrorBeCaught() {
  setTimeout(function callbackFunction() {
    try {
        throw new Error(&#39;There was a problem&#39;);
    } catch (error) {
      console.warn(&#39;There was a problem&#39;);
      
      // Placeholder for fallback implementation
    }
  }, 3000);
}

willErrorBeCaught();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now upon &lt;code&gt;throw&lt;/code&gt; the &amp;quot;control will be passed to the first catch block in the
call stack&amp;quot; which is the one from the currently executed function, i.e.
&lt;code&gt;callbackFunction&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/65919843/catch-block-wrapping-a-function-that-throws-inside-a-settimeout-not-executed&quot;&gt;Catch block wrapping a function that throws inside a setTimeout not executed |
stackoverflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw&quot;&gt;MDN Docs article about &lt;code&gt;throw&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Fri, 24 Oct 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-use-settimeout-throw-and-try-catch-blocks/</guid>
    </item>
    <item>
       <title>Using Orca to Evaluate Web Accessibility</title>
       <link>https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/</link>
       <description>&lt;p&gt;This guide is profoundly inspired from &lt;a href=&quot;https://webaim.org/articles/voiceover/&quot;&gt;WebAIM&#39;s &amp;quot;Using VoiceOver to Evaluate
Web Accessibility&amp;quot;&lt;/a&gt; article, but applied to Orca&#39;s screen reader. It
deliberately follows the same content structure, as WebAIM offers a very well
structured article that, in my opinion, fits the basic needs of a Web
professional who aims at testing their User Interfaces with a screen reader
under a Linux GNOME desktop environment.&lt;br /&gt;
Moreover, I could not have come up with a smarter structure to be very honest.&lt;/p&gt;
&lt;h2&gt;Article content&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#getting-started&quot;&gt;Getting started&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#configure-orca&quot;&gt;Configure Orca&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#configure-orca-modifier-key&quot;&gt;Configure Orca modifier key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#configure-orca-voice&quot;&gt;Configure Orca voice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#reading&quot;&gt;Reading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#navigation&quot;&gt;Navigation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#single-key-navigation-shortcuts&quot;&gt;Single-key navigation shortcuts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#other-navigation-shortcuts&quot;&gt;Other navigation shortcuts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#images&quot;&gt;Images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#data-tables&quot;&gt;Data Tables&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#other-data-tables-navigation-shortcuts&quot;&gt;Other Data Tables navigation shortcuts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#forms&quot;&gt;Forms&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#focus-and-browse-modes&quot;&gt;Focus and Browse modes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#practice&quot;&gt;Practice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/#references-and-resources&quot;&gt;References and resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://orca.gnome.org/&quot;&gt;Orca&lt;/a&gt; is a free, open source, flexible, and extensible screen reader that
provides access to the graphical desktop via speech and refreshable braille.&lt;/p&gt;
&lt;p&gt;Orca is available on Linux and is being continuously developed as part of the
GNOME project.&lt;br /&gt;
It comes out of the box with Ubuntu!&lt;/p&gt;
&lt;p&gt;While reading this article, keep a few things in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This article does not contain a comprehensive list of Orca shortcuts. It does
provide a list of the &lt;em&gt;essential&lt;/em&gt; commands that new or novice Orca users
should know. For a more comprehensive list of Orca keyboard shortcuts, see the
&lt;a href=&quot;https://gnome.pages.gitlab.gnome.org/orca/help/commands.html&quot;&gt;Orca&#39;s commands page from Orca Screen Reader documentation&lt;/a&gt;. The &lt;a href=&quot;https://gnome.pages.gitlab.gnome.org/orca/help/index.html#getting_started&quot;&gt;Orca
Getting started guide&lt;/a&gt; is also available.&lt;/li&gt;
&lt;li&gt;If you are new to screen readers, plan on spending some time (perhaps several
hours) becoming comfortable using Orca. Don&#39;t get discouraged if things
still seem confusing after only a few minutes. Slow down the reading speed and
take your time.&lt;/li&gt;
&lt;li&gt;While Orca works with Web browsers, including Firefox and Chrome/Chromium that
support the Assistive Technology Service Provider Interface (AT-SPI), which is
the primary assistive technology infrastructure for Linux and Solaris, this
guide will primarily focus on using Orca with Firefox under Ubuntu as according
to latest &amp;quot;WebAIM&#39;s screen reader survey&amp;quot; from 2024, Firefox is the browser that
is most commonly combined with Orca.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Getting started&lt;/h2&gt;
&lt;p&gt;There are few methods to start (or stop) Orca.&lt;/p&gt;
&lt;p&gt;The simplest way is to use the key binding
&lt;kbd&gt;Super&lt;/kbd&gt;+&lt;kbd&gt;Alt&lt;/kbd&gt;+&lt;kbd&gt;S&lt;/kbd&gt;.&lt;br /&gt;
The &lt;kbd&gt;Super&lt;/kbd&gt; key is an alternative name for what is commonly labelled as
the Windows key or Command key on modern keyboards.&lt;/p&gt;
&lt;p&gt;The more tedious way, but that may offer &lt;a href=&quot;https://gnome.pages.gitlab.gnome.org/orca/help/introduction.html#loadtime&quot;&gt;load-time options&lt;/a&gt;, is to type
&lt;code&gt;orca&lt;/code&gt;, along with any optional parameters, in a Terminal window or within the
Run dialog and then press &lt;kbd&gt;Enter&lt;/kbd&gt;.&lt;br /&gt;
To stop it when using the Terminal window, press &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;C&lt;/kbd&gt;.&lt;br /&gt;
To stop it when using the Run dialog, launch the Run dialog again, type &lt;code&gt;killall orca&lt;/code&gt; and the press &lt;kbd&gt;Enter&lt;/kbd&gt;.&lt;/p&gt;
&lt;p&gt;The Orca Modifier key, called &lt;strong&gt;Orca&lt;/strong&gt; key and later denoted as
&lt;kbd&gt;Orca&lt;/kbd&gt; in this page, can be among the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;Numpad 0&lt;/kbd&gt; referenced as &amp;quot;KP_Insert&amp;quot; in the settings&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Insert&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Insert&lt;/kbd&gt;, &lt;kbd&gt;Numpad 0&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Caps Lock&lt;/kbd&gt; referenced as &amp;quot;Caps_Lock&amp;quot; in the settings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which key the Orca Modifier is bound to will, by default, depend on whether
you are using Orca&#39;s Laptop keyboard layout or its Desktop keyboard layout.&lt;br /&gt;
This article will only focus on Laptop keyboard layout.&lt;br /&gt;
The Desktop keyboard layout key bindings can be found &lt;a href=&quot;https://gnome.pages.gitlab.gnome.org/orca/help/index.html&quot;&gt;Orca&#39;s screen reader
documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While working in Orca, keep the following in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Orca currently functions best with Firefox. Orca works with Chrome/Chromium,
but some errors may be introduced. Orca can also access applications including
such as LibreOffice. This article will only focus on accessing web content with
Firefox.&lt;/li&gt;
&lt;li&gt;Remember that screen reader users typically do not use a mouse. As you become
more comfortable with Orca, try using only the keyboard.&lt;/li&gt;
&lt;li&gt;Most browser shortcut keys will work when using Orca.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Configure Orca&lt;/h3&gt;
&lt;h4&gt;Configure Orca modifier key&lt;/h4&gt;
&lt;p&gt;If you will to configure the Orca modifier key,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Access the &amp;quot;Screen reader preferences&amp;quot; dialog. To bring up this dialog,
execute  &lt;code&gt;orca -s&lt;/code&gt; from your Terminal or the &amp;quot;Run dialog&amp;quot;.&lt;/li&gt;
&lt;li&gt;Move to the &amp;quot;Key Bindings&amp;quot; page&lt;/li&gt;
&lt;li&gt;Move to the &amp;quot;Screen Reader Modifier Key(s)&amp;quot; combobox&lt;/li&gt;
&lt;li&gt;Select the desired modifier from the combobox options.&lt;/li&gt;
&lt;li&gt;Press the &amp;quot;Apply&amp;quot; button.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These keys are used to access special Orca commands and functions and will
be referenced simply as &lt;kbd&gt;Orca&lt;/kbd&gt; in this pages onward.&lt;/p&gt;
&lt;p&gt;For example &lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt;, which equates to
&lt;kbd&gt;Insert&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt;, if &lt;kbd&gt;Insert&lt;/kbd&gt; is configured as the
Orca modifier key, will open Orca preferences dialog.&lt;/p&gt;
&lt;h3&gt;Configure Orca voice&lt;/h3&gt;
&lt;p&gt;Now that you will be spending time using it, you would better set an Orca voice
preference. To do so, open the &amp;quot;Screen reader preferences&amp;quot; dialog and move to
the &amp;quot;Voice&amp;quot; page, and then configure to your liking.&lt;/p&gt;
&lt;p&gt;Be it that you are not content enough with the set of voices available, you may
consider researching online for others that can be used by Orca.&lt;/p&gt;
&lt;p&gt;You may consider &lt;a href=&quot;https://rhvoice.org/&quot;&gt;RHVoice, a free and open-source multilingual speech
synthesizer&lt;/a&gt; compatible with Orca.&lt;br /&gt;
Refer to &amp;quot;&lt;a href=&quot;https://rhvoice.org/linux/&quot;&gt;Using RHVoice on Linux&lt;/a&gt;&amp;quot; to set it up on your linux machine. After
you reboot and return the Screen reader &amp;quot;Voice&amp;quot; preferences you should be able
to pick &amp;quot;rhvoice&amp;quot; from the &amp;quot;Speech synthesizer&amp;quot; combobox.&lt;/p&gt;
&lt;p&gt;In the list below are other voices options you can explore:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://voxin.oralux.net/index.php&quot;&gt;Voxin&lt;/a&gt; ($20 in average per voice): An easily installable add-on which
provides text-to-speech to blind users of GNU/Linux. It offers many
proprietary voices in many languages, many of which sound very good. Some may
recognise Samantha, the default VoiceOver voice.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rhasspy.github.io/piper-samples/&quot;&gt;Piper&lt;/a&gt; (Free): Set of voices that are quite realistic, generally too slow
for screen reader use, although it seems to work well for some as this &lt;a href=&quot;https://gist.github.com/C-Loftus/5c71ebef18717a364e1ac2865a54e1e9&quot;&gt;&amp;quot;Use
the Orca Screen Reader with Piper&amp;quot; gist&lt;/a&gt; testifies.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Reading&lt;/h2&gt;
&lt;p&gt;There are dozens of keyboard shortcuts that allow you to read web content.&lt;/p&gt;
&lt;p&gt;The following is a list of essential reading shortcuts. With these shortcuts,
you should be able to read through most web content with Orca.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;;&lt;/kbd&gt;: Start reading at current position (also know
as &amp;quot;Say all&amp;quot;)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;Shift&lt;/kbd&gt; +  &lt;kbd&gt;↑&lt;/kbd&gt;: Speak current
selection&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;←&lt;/kbd&gt;/&lt;kbd&gt;→&lt;/kbd&gt;: Move and read Previous/Next character&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;←&lt;/kbd&gt;/&lt;kbd&gt;→&lt;/kbd&gt;: Move and read Previous/Next word&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;↑&lt;/kbd&gt;/&lt;kbd&gt;↓&lt;/kbd&gt;: Move and read Previous/Next line&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;/&lt;/kbd&gt;: Present the title bar&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;V&lt;/kbd&gt;: Toggle verbosity level (&amp;quot;brief&amp;quot; or &amp;quot;verbose&amp;quot;)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt;: Stop reading&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;S&lt;/kbd&gt;: Turn speech on and off. Extremely convenient
as it sits half-way between &amp;quot;Stop reading&amp;quot; and &amp;quot;Stop Orca&amp;quot;. It prevents Orca
from &amp;quot;speaking&amp;quot; along all your moves and actions (e.g.switching
window/application or operating your keyboard).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You may want to practice reading through the content on this page with Orca
right now.&lt;/p&gt;
&lt;h2&gt;Navigation&lt;/h2&gt;
&lt;p&gt;Sighted users visually navigate through web content in a number of ways. They
skim for headings, lists, tables, etc. Most of these methods are available to
Orca users if the web page is correctly structured and well organised.&lt;/p&gt;
&lt;p&gt;There are several single-key shortcuts to quickly navigate by common page
elements.&lt;/p&gt;
&lt;h3&gt;Single-key navigation shortcuts&lt;/h3&gt;
&lt;p&gt;There are several single-key shortcuts to quickly navigate by common page
elements. Orca offers this feature through its &amp;quot;Structural navigation&amp;quot; mode.&lt;/p&gt;
&lt;p&gt;To use this mode, you first you need to switch it on with:&lt;br /&gt;
&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;Z&lt;/kbd&gt;.&lt;/p&gt;
&lt;p&gt;These single-key shortcuts include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;Tab&lt;/kbd&gt;: Links and form controls&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;H&lt;/kbd&gt;: Headings&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;1&lt;/kbd&gt; - &lt;kbd&gt;6&lt;/kbd&gt;: Headings level 1-6&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;F&lt;/kbd&gt;: Form controls&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;B&lt;/kbd&gt;: Buttons&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;C&lt;/kbd&gt;: Combo boxes&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;E&lt;/kbd&gt;: Entries i.e. Text inputs&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;R&lt;/kbd&gt;: Radio buttons&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;X&lt;/kbd&gt;: Checkboxes&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;T&lt;/kbd&gt;: Tables&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;K&lt;/kbd&gt;: Links (mnemonic: Link ends with &lt;em&gt;K&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;U&lt;/kbd&gt;: Unvisited link&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;V&lt;/kbd&gt;: Visited link&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;G&lt;/kbd&gt;: Graphics i.e. Images&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;L&lt;/kbd&gt;: Lists&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;I&lt;/kbd&gt;: Items in a list&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;P&lt;/kbd&gt;: Paragraph&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;B&lt;/kbd&gt;: Blockquote&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;M&lt;/kbd&gt;: Landmarks (mnemonic: &lt;em&gt;M&lt;/em&gt; like Mark)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;S&lt;/kbd&gt;: Separators&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;Shift&lt;/kbd&gt; + any of these keys will allow to navigate in reverse.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Alt&lt;/kbd&gt; any of these keys brings up a dialog
with the list of all items of type (e.g. all Headings, all Headings of level
2, all Links...).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Other navigation shortcuts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;[&lt;/kbd&gt;: Open the Find dialog&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;]&lt;/kbd&gt;: Search for the next instance of a string&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;]&lt;/kbd&gt;: Search for the previous instance of a string&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can &lt;a href=&quot;https://gnome.pages.gitlab.gnome.org/orca/help/howto_orca_find.html&quot;&gt;read more about Orca Find on Orca Screen Reader documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Images&lt;/h2&gt;
&lt;p&gt;An image&#39;s &lt;a href=&quot;https://webaim.org/techniques/alttext/&quot;&gt;alternative text&lt;/a&gt; will be read by Orca. If alternative text is not
defined, Orca will typically ignore it, except in some cases where the image has
a function (e.g. image is a link).&lt;/p&gt;
&lt;p&gt;WebAIM put together an &lt;a href=&quot;https://webaim.org/articles/voiceover/images&quot;&gt;Image examples and practice page&lt;/a&gt; that you can use and
explore with Orca. Note that this page is branded for VoiceOver but its content
is as relevant for Orca than it is for VoiceOver.&lt;/p&gt;
&lt;h2&gt;Data Tables&lt;/h2&gt;
&lt;p&gt;To navigate to the next table in a page, press the &lt;kbd&gt;T&lt;/kbd&gt;. To navigate
within a &lt;a href=&quot;https://webaim.org/techniques/tables/data&quot;&gt;data table&lt;/a&gt;, hold down &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Alt&lt;/kbd&gt; + an arrow key to go to the adjacent cell
according to direction dictated by the pressed arrow key. If a table has proper
row and column headers, they will be read automatically while navigating.&lt;/p&gt;
&lt;p&gt;WebAIM put together a &lt;a href=&quot;https://webaim.org/articles/nvda/tables.htm&quot;&gt;Table examples and practice page&lt;/a&gt; that you can use and
explore with Orca. Note that this page is branded for NVDA but its content is as
relevant for Orca than it is for NVDA if you skip the &amp;quot;Data tables&amp;quot; section that
mentions shortcuts relevant to NVDA only.&lt;/p&gt;
&lt;h3&gt;Other Data Tables navigation shortcuts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;F11&lt;/kbd&gt;: Toggle cell/row reading&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Alt&lt;/kbd&gt; + &lt;kbd&gt;Home&lt;/kbd&gt;: Go to first cell in table&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Alt&lt;/kbd&gt; + &lt;kbd&gt;End&lt;/kbd&gt;: Go to last cell in table&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Forms&lt;/h2&gt;
&lt;p&gt;When a &lt;a href=&quot;https://webaim.org/techniques/forms/&quot;&gt;form control&lt;/a&gt; gets keyboard focus, its label is read by Orca, and then
the type of form control. If a group of form controls—typically groups of
checkboxes or radio buttons—is contained in a fieldset with a legend, Orca
presents items in a fieldset as a group and reads the legend when you first
navigate to anything within the group.&lt;/p&gt;
&lt;p&gt;Use the following browser keyboard controls to interact with form controls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;Tab&lt;/kbd&gt; and &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Tab&lt;/kbd&gt;: Navigate forward/backward through form controls.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Space&lt;/kbd&gt;: Select and deselect checkboxes.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;↑&lt;/kbd&gt;/&lt;kbd&gt;↓&lt;/kbd&gt;: Select from a group of radio buttons.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;↑&lt;/kbd&gt;/&lt;kbd&gt;↓&lt;/kbd&gt; or the first letter of an option: Select an option in a combo box&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;Enter&lt;/kbd&gt;: Submit a form&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;WebAIM put together a &lt;a href=&quot;https://webaim.org/articles/nvda/forms.htm&quot;&gt;Form examples and practice page&lt;/a&gt; that you can use and
explore with Orca. Note that this page is branded for NVDA but its content is as
relevant for Orca than it is for NVDA.&lt;/p&gt;
&lt;h3&gt;Focus and Browse modes&lt;/h3&gt;
&lt;p&gt;Since screen readers use many of the keys on the keyboard for quick navigation,
filling in a form or interacting with a widget presents a dilemma. For example,
when pressing &lt;kbd&gt;H&lt;/kbd&gt;, how does a screen reader know if you want to
navigate to the next heading or enter the letter into a textbox?&lt;/p&gt;
&lt;p&gt;Orca takes care of this by switching between two &amp;quot;modes.&amp;quot; &amp;quot;Browse mode&amp;quot; is the
default mode for reading and navigating the page—the mode where &lt;kbd&gt;H&lt;/kbd&gt;
takes you to the next heading. &amp;quot;Focus mode&amp;quot; passes almost all keystrokes on to
the browser—the mode where &lt;kbd&gt;H&lt;/kbd&gt; puts the letter H in a text box.&lt;/p&gt;
&lt;p&gt;Orca will automatically turn on focus mode when you use structural navigation
commands to navigate to a form field. For example, pressing &lt;kbd&gt;E&lt;/kbd&gt; to move
to the next entry would move focus there and also turn focus mode on so that
your next press of &lt;kbd&gt;E&lt;/kbd&gt; would type an “e” into that entry.&lt;br /&gt;
In order to start or stop interacting with the focused form field, use Orca
Modifier+A to switch between browse mode and focus mode.&lt;/p&gt;
&lt;h2&gt;Practice&lt;/h2&gt;
&lt;p&gt;Take the current page, apply your some of your learnings. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Switch Orca on&lt;/li&gt;
&lt;li&gt;Listen&lt;/li&gt;
&lt;li&gt;Tell Orca to stop reading&lt;/li&gt;
&lt;li&gt;Start reading at at current position&lt;/li&gt;
&lt;li&gt;Turn off speech&lt;/li&gt;
&lt;li&gt;Turn on speech&lt;/li&gt;
&lt;li&gt;Present the title bar&lt;/li&gt;
&lt;li&gt;Use &lt;kbd&gt;Orca&lt;/kbd&gt; + &lt;kbd&gt;Z&lt;/kbd&gt; to switch to structural navigation
&lt;ul&gt;
&lt;li&gt;Navigate forward by headings (either &lt;kbd&gt;H&lt;/kbd&gt; or &lt;kbd&gt;1&lt;/kbd&gt; -
&lt;kbd&gt;3&lt;/kbd&gt;)&lt;/li&gt;
&lt;li&gt;Navigate backward by headings (either &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;H&lt;/kbd&gt; or
&lt;kbd&gt;1&lt;/kbd&gt; - &lt;kbd&gt;3&lt;/kbd&gt;)&lt;/li&gt;
&lt;li&gt;Navigate forward and backward by items of others types e.g.:
&lt;ul&gt;
&lt;li&gt;links (&lt;kbd&gt;K&lt;/kbd&gt;, &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;K&lt;/kbd&gt;)&lt;/li&gt;
&lt;li&gt;paragraphs (&lt;kbd&gt;P&lt;/kbd&gt;, &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;P&lt;/kbd&gt;)&lt;/li&gt;
&lt;li&gt;list (&lt;kbd&gt;L&lt;/kbd&gt;, &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;L&lt;/kbd&gt;)&lt;/li&gt;
&lt;li&gt;landmarks (&lt;kbd&gt;M&lt;/kbd&gt;, &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;M&lt;/kbd&gt;)&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Go navigate and interact with WebAIM&#39;s example pages:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://webaim.org/articles/voiceover/images&quot;&gt;Image examples and practice page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://webaim.org/articles/nvda/tables.htm&quot;&gt;Table examples and practice page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://webaim.org/articles/nvda/forms.htm&quot;&gt;Form examples and practice page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Switch Orca off&lt;/li&gt;
&lt;li&gt;Turn off the monitor and repeat some of these tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;References and resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gnome.pages.gitlab.gnome.org/orca/help/index.html#getting_started&quot;&gt;Orca Getting started guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Assistive_Technology_Service_Provider_Interface#Support&quot;&gt;Assistive Technology Service Provider Interface &amp;gt; Support - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rhvoice.org/&quot;&gt;RHVoice, a free and open-source multilingual speech synthesizer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://webaim.org/articles/voiceover/&quot;&gt;WebAIM&#39;s &amp;quot;Using VoiceOver to Evaluate Web Accessibility&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://webaim.org/articles/nvda/&quot;&gt;WebAIM&#39;s &amp;quot;Using NVDA to Evaluate Web Accessibility&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://webaim.org/articles/#html&quot;&gt;WebAIM&#39;s &amp;quot;HTML, ARIA, and CSS Accessibility articles&amp;quot; serie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/C-Loftus/orca-intro-guide/blob/main/cheatsheet.md&quot;&gt;Orca screen reader (laptop layout) one-page reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/C-Loftus/orca-intro-guide?tab=readme-ov-file&quot;&gt;&amp;quot;Orca Screen Reader Intro Guide&amp;quot; repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=mDVG0DfwuxQ&quot;&gt;&amp;quot;Introduction to Orca Screen reader for Linux&amp;quot; video by ZAccess on YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=biPtbcrLY3Q&quot;&gt;&amp;quot;Ubuntu Summit 2022 | Simple web accessibility checks - featuring Orca&amp;quot; video by Ubuntu OnAir on YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Fri, 18 Jul 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/using-orca-to-evaluate-web-accessibility/</guid>
    </item>
    <item>
       <title>How to mock `console.error` or other `console` methods with Jest</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-mock-console-error-or-other-console-methods-with-jest/</link>
       <description>&lt;p&gt;Today a quick one I tend to always hunt into older code I authored to remember
how to do it. So to serve my future self as well as benefit the community, here
is how one can mock &lt;code&gt;console&lt;/code&gt; methods with the Jest testing framework.&lt;/p&gt;
&lt;p&gt;Let&#39;s go over an hopefully straight-forward example that mocks the
&lt;code&gt;console.error&lt;/code&gt; method:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;describe(&#39;My super duper component&#39;, async () =&amp;gt; {
  let consoleErrorSpy;

  beforeEach(() =&amp;gt; {
      errorSpy = jest.spyOn(global.console, &#39;error&#39;).mockImplementation(() =&amp;gt; {});
      // Hint: It could work without the `.mockImplementation...` part but
      // your Jest run output would be cluttered with the errors printed out.
  });

  afterEach(() =&amp;gt; {
      errorSpy.mockRestore();
  });

  it(&#39;logs an error if the wrapper is `undefined`&#39;, () =&amp;gt; {
    mySuperDuperComponent(/* missing `wrapper` argument */);

    expect(errorSpy).toHaveBeenCalledTimes(1); // i.e it has been called once
    expect(errorSpy).toHaveBeenCalledWith(&#39;Could not init super duper component. Wrapper not found.&#39;);
  });

  // ...
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the other &lt;code&gt;console&lt;/code&gt; methods, just swap &lt;code&gt;error&lt;/code&gt; and &lt;code&gt;Error&lt;/code&gt; with their
equivalent (e.g. &lt;code&gt;warn&lt;/code&gt; and &lt;code&gt;Warn&lt;/code&gt;, &lt;code&gt;log&lt;/code&gt; and &lt;code&gt;Log&lt;/code&gt;...).&lt;/p&gt;
</description>
       <pubDate>Tue, 01 Jul 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-mock-console-error-or-other-console-methods-with-jest/</guid>
    </item>
    <item>
       <title>Make your &#39;Script error.&#39; issues more insightful in Sentry</title>
       <link>https://morgan.cugerone.com/blog/make-your-script-error-issues-more-insightful-in-sentry/</link>
       <description>&lt;h2&gt;Context and problem&lt;/h2&gt;
&lt;p&gt;For quite some time we had our &lt;a href=&quot;https://sentry.io/&quot;&gt;Sentry&lt;/a&gt; monitoring capturing the following
very unperceptive error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Event &lt;code&gt;ErrorEvent&lt;/code&gt; captured as exception with message &lt;code&gt;Script error.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Eventually I landed on this rather comprehensive Sentry answers article:
&lt;a href=&quot;https://sentry.io/answers/script-error/&quot;&gt;What is &amp;quot;Script Error&amp;quot;?&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;According to the article...&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Script error” is what browsers send to the &lt;code&gt;onerror&lt;/code&gt; callback when an error
originates from a JavaScript file served from a different origin (different
domain, port, or protocol).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The article gives the recommendation of using &lt;code&gt;crossorigin=&amp;quot;anonymous&amp;quot;&lt;/code&gt; on the
script that originated the error.&lt;/p&gt;
&lt;p&gt;The problem is that the exception captured in Sentry has absolutely no reference
to the culprit script, leaving us clueless on how to address the issue.&lt;/p&gt;
&lt;h2&gt;Vision of an improvement&lt;/h2&gt;
&lt;p&gt;The obvious improvement would be to be provided with the name of the culprit
script.&lt;/p&gt;
&lt;p&gt;At best, to be pointed at the line, in that script, that originated the
unhandled exception.&lt;/p&gt;
&lt;h2&gt;A solution&lt;/h2&gt;
&lt;p&gt;Experimenting with the &lt;code&gt;window.error&lt;/code&gt; callback presented in the article, I was
able to log the &lt;code&gt;url&lt;/code&gt; argument that revealed the chased script.&lt;/p&gt;
&lt;p&gt;Now, it was a matter of figuring out how to tell Sentry to let us send them a
better formatted error message, that would include the clue about which script
is the culprit, as well as some insight how to get even more details.&lt;/p&gt;
&lt;p&gt;This is how I made it all work...&lt;/p&gt;
&lt;p&gt;First, in the configuration passed to the &lt;code&gt;Sentry.init()&lt;/code&gt; function call, make
sure to include within the &lt;code&gt;ignoreErrors&lt;/code&gt; array the string: &lt;code&gt;&#39;Script error.&#39;&lt;/code&gt;.
That basically tells Sentry to ignore this error all together.&lt;/p&gt;
&lt;p&gt;Secondly, where appropriate in your use case, include a &lt;code&gt;window.onerror&lt;/code&gt;
callback definition like the one below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/**
 * Customises specific error before capturing to Sentry. It aims at providing
 * more insights than what the default Sentry capture would do for such errors.
 *
 * The parameters are the one provided by the `window.onerror` callback.
 *
 * @param {string} message Error message.
 * @param {string} url URL of the script which threw the exception.
 * @param {object} [error] Error being thrown.
 */
function addSentryOverrides(message, url, error) {
  // Warning: For this to work, &#39;Script error.&#39; should be added to Sentry.init
	// `ignoreErrors` list.
	if (error === undefined &amp;amp;&amp;amp; message &amp;amp;&amp;amp; message.includes(&#39;Script error.&#39;)) {
		const formattedMessage = `Unhandled exception in script ${url}. Hint: Add &#92;`crossorigin=&amp;quot;anonymous&amp;quot;&#92;` on the script tag to know the type of error and the position of the error`;

		const scriptError = new Error(formattedMessage);
		scriptError.name = &#39;ScriptError&#39;;

		Sentry.captureException(scriptError);
	}
}

window.onerror = function (message, url, _line, _column, error) {
	addSentryOverrides(message, url, error);
};

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Testing out the solution&lt;/h3&gt;
&lt;p&gt;In order to test out this solution, I created a temporary script over at &lt;a href=&quot;https://staticsave.com/&quot;&gt;Static
Save&lt;/a&gt; that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  bar();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When calling &lt;code&gt;foo()&lt;/code&gt; this should blow up as &lt;code&gt;bar()&lt;/code&gt; is not defined.&lt;/p&gt;
&lt;p&gt;Now let&#39;s use this...&lt;/p&gt;
&lt;p&gt;After loading the page I use for the test; in the developer console, I went
ahead and appended the temporary script programmatically as below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var culpritRemoteScript = document.createElement(&#39;script&#39;);

culpritRemoteScript.setAttribute(&#39;src&#39;,&#39;https://temp.staticsave.com/68525ff025b09.js&#39;);
document.body.appendChild(culpritRemoteScript);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I then executed the below snippet in order to trigger the exception upon a user
click interaction.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Clicking the Home link will generate an Unhandled exception
document
  .querySelector(&#39;[data-test=&amp;quot;home-link&amp;quot;]&#39;)
  .addEventListener(&#39;click&#39;, function clickEventHandler(event) {
  event.preventDefault();
	foo();  
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, as soon as we click the &amp;quot;Home&amp;quot; anchor link, the &lt;code&gt;foo()&lt;/code&gt; function will be
called, what in turns will be caught into the &lt;code&gt;window.error&lt;/code&gt; callback defined
previously, what would finally capture the following exception in Sentry:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ScriptError&lt;/strong&gt;&lt;br /&gt;
Unhandled exception in script &lt;em&gt;https://temp.staticsave.com/68525ff025b09.js&lt;/em&gt;. Hint: Add &lt;code&gt;crossorigin=&amp;quot;anonymous&amp;quot;&lt;/code&gt; on the script tag to know the type of error and the position of the error&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is much more insightful, isn&#39;t it?&lt;/p&gt;
&lt;h2&gt;Sentry benefit from following the provided hint&lt;/h2&gt;
&lt;p&gt;Taken that we follow the &amp;quot;Hint&amp;quot; of adding the &lt;code&gt;crossorigin&lt;/code&gt; attribute to the
remote script, Sentry seems to capture the exception beautifully, in the sense
that, it turns into the following error message and stack trace&lt;/p&gt;
&lt;p&gt;Message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ReferenceError&lt;/strong&gt;&lt;br /&gt;
bar is not defined&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Strack trace:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ReferenceError: baz is not defined&lt;br /&gt;
  at bar(/68525ff025b09.js:2:3)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As you can see it now reveals quite some insights: the error type, the script
filename, and the position of the statement that threw the exception.&lt;/p&gt;
&lt;p&gt;We are therefore better equipped to go and fix that bug.&lt;/p&gt;
&lt;h2&gt;Sharing is caring&lt;/h2&gt;
&lt;p&gt;I spent quite some time in researching how to address this inconvenience, as
well as, crafting this solution.&lt;/p&gt;
&lt;p&gt;I therefore hope that, if you find yourself in this situation, your path will
cross this blog post and that it will fit to your need and make your day
brighter 😉.&lt;/p&gt;
&lt;p&gt;If you find any problem with the proposed solution and/or have a better
approach, do not hesitate to reach out. So far this is the best one I think of.&lt;/p&gt;
</description>
       <pubDate>Wed, 18 Jun 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/make-your-script-error-issues-more-insightful-in-sentry/</guid>
    </item>
    <item>
       <title>Today I learned: Jest used with JSDOM as environment does not support navigation, full stop!</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-jest-used-with-jsdom-as-environment-does-not-support-navigation-full-stop/</link>
       <description>&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;JSDOM does not support Navigation to different pages.&lt;/p&gt;
&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;I use the Jest testing framework, configured to use JSDOM as environment.&lt;/p&gt;
&lt;p&gt;After failing to write a test that asserts clicking on a link would navigate to
a new page, I spent hours researching for a solution. That was only to realised
it is mission impossible. Jest is not to blame though!&lt;/p&gt;
&lt;p&gt;At this point, to be very honest, the only one to blame may be me. Indeed what I
was trying to does not make so much sense as the navigation in my use case is
not instructed by Javascript but through the default behaviour of HTML anchor
links.&lt;br /&gt;
I believe I got trapped by the fact that in the past, I mapped some mouse and
keyboard interactions in Jes. These though only involved changes to be asserted
onto the current page and therefore made sense and were functioning.&lt;/p&gt;
&lt;p&gt;In case you are using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Location/assign&quot;&gt;&lt;code&gt;Location.assign(url)&lt;/code&gt;&lt;/a&gt; in your implementation, you may
be interested into reading Ben Ilegbodu&#39;s post: &lt;a href=&quot;https://www.benmvp.com/blog/mocking-window-location-methods-jest-jsdom/&quot;&gt;Mocking window.location methods
in Jest &amp;amp; jsdom&lt;/a&gt;. It is a use case worth a cover in your tests suite.&lt;/p&gt;
&lt;h2&gt;Learning&lt;/h2&gt;
&lt;p&gt;Crawling through loads of Github issues, Stackoverflow threads and blog posts...
I landed on the JSDOM documentation which mentions it &amp;quot;does not handle
navigation&amp;quot;, full stop.&lt;br /&gt;
It explains that clicking a link will change nothing, i.e &amp;quot;there will be no
new Window or Document object, and the existing window&#39;s location object will
still have all the same property values&amp;quot;.&lt;/p&gt;
&lt;p&gt;This confirms we cannot assert a link click default behaviour because the way to
do that would have been to check for the value of
&lt;code&gt;window.document.location.href&lt;/code&gt;, but it won&#39;t change!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;JSDOM is not a Web Browser nor a Web driver and therefore has no primary
interests on implementing Navigation. It emulates the DOM, what implies the
current Document Object Model. Although it is also used for scraping websites,
it expects its consumers to direct it to the pages to be scraped rather than
offer crawling/navigation support. It&#39;s fair!&lt;br /&gt;
In the JavaScript ecosystem, PhantomJS is better suited candidate for such use
cases.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jsdom/jsdom#readme&quot;&gt;jsdom/jsdom: A JavaScript implementation of various web standards, for use with Node.js&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-jest-used-with-jsdom-as-environment-does-not-support-navigation-full-stop/</guid>
    </item>
    <item>
       <title>Today I learned: How to use a Sass variable within a CSS property (a.k.a variable) value</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-use-use-a-sass-variable-in-a-css-property-aka-variable-value/</link>
       <description>&lt;p&gt;In order to do that, you need to interpolate the Sass variable, using the
&lt;code&gt;#{$your-sass-variable-name}&lt;/code&gt; notation.&lt;br /&gt;
This may not be enough if the Sass variable contains quotations marks.&lt;/p&gt;
&lt;p&gt;In some instance you should combine the previous notation with the
&lt;code&gt;meta.inspect()&lt;/code&gt; function in order to preserve the quotes.&lt;/p&gt;
&lt;p&gt;Here are examples of the both variants:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sass&quot;&gt;$accent-color: #fbbc04;
$font-family-monospace: Menlo, Consolas, &amp;quot;Courier New&amp;quot;, monospace;

:root {
  --accent-color-right: #{$accent-color};
  --font-family-monospace: #{meta.inspect($font-family-monospace)};
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;: &lt;a href=&quot;https://sass-lang.com/documentation/breaking-changes/css-vars/&quot;&gt;Breaking Change: CSS Variable Syntax on sass-lang.com&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Fri, 04 Apr 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-use-use-a-sass-variable-in-a-css-property-aka-variable-value/</guid>
    </item>
    <item>
       <title>Today I learned: How to append the parent selector at the end of a Sass rule declaration</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-append-the-parent-selector-at-the-end-of-a-sass-rule-declaration/</link>
       <description>&lt;h2&gt;Heads up&lt;/h2&gt;
&lt;p&gt;Regarding the below examples... Of course this approach sounds
over-engineered, but here, the purpose is educational, and therefore using
simple examples to demonstrate the Sass language capability seemed appropriate.&lt;/p&gt;
&lt;h2&gt;Base design&lt;/h2&gt;
&lt;p&gt;Let&#39;s take the simple below Sass declarations:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sass&quot;&gt;.sidebar {
  .cta {
    background-color: teal;
    color: white;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, all Call To Actions (a.k.a CTA) from the sidebar have a
background of &lt;code&gt;teal&lt;/code&gt; and a text color of &lt;code&gt;white&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The CSS output for this is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.sidebar .cta {
  background-color: teal;
  color: white;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&amp;quot;Power users&amp;quot; design&lt;/h2&gt;
&lt;p&gt;Now let&#39;s say that you have &amp;quot;power users&amp;quot; who should, by design, experience an
alternative branding for these sidebar CTAs.&lt;/p&gt;
&lt;p&gt;In order to customise various elements and components in the page, it has been
decided to position a &lt;code&gt;power-user&lt;/code&gt; CSS class on the highest page element, i.e
the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;
&lt;p&gt;To add to that; you want to keep the override of the branding close to its
original definition in your Sass file.&lt;/p&gt;
&lt;p&gt;This is where you need to append the parent selector, from within a nesting
block, with the &lt;code&gt;.power-user&lt;/code&gt; selector.  You can achieve that using &lt;a href=&quot;https://sass-lang.com/documentation/at-rules/at-root/&quot;&gt;Sass&#39;
&lt;code&gt;@at-root&lt;/code&gt; &lt;em&gt;at-rule&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now let&#39;s revisit our example from above and add the custom &amp;quot;power user&amp;quot;
branding.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sass&quot;&gt;.sidebar {
  .cta {
    background-color: teal;
    color: white;

    @at-root .power-user #{&amp;amp;} {
        background-color: orangered;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The CSS output for this is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.sidebar .cta {
  background-color: teal;
  color: white;
}
.power-user .sidebar .cta {
  background-color: orangered;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et voilà! You get the &lt;code&gt;.power-user .sidebar .cta {}&lt;/code&gt; rule you were aiming for.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/16108103/append-the-parent-selector-to-the-end-with-sass&quot;&gt;Append the parent selector to the end with Sass | Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sass-lang.com/documentation/at-rules/at-root/&quot;&gt;Sass&#39; &lt;code&gt;@at-root&lt;/code&gt; &lt;em&gt;at-rule&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Fri, 04 Apr 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-append-the-parent-selector-at-the-end-of-a-sass-rule-declaration/</guid>
    </item>
    <item>
       <title>Today I learned: How to use .env files natively with Node.js</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-use-env-files-natively-with-nodejs/</link>
       <description>&lt;p&gt;Since Node.js 20 you can specify &lt;code&gt;--env-file&lt;/code&gt; arguments.&lt;/p&gt;
&lt;p&gt;This may cover most of your needs and we may not need the cumbersome &lt;code&gt;npm config set script-shell &amp;quot;/bin/bash&amp;quot;; source ./.env;&lt;/code&gt; prefix to your node commands
anymore or even this extra &lt;code&gt;dotenv&lt;/code&gt; library you may have dropped into your
project&#39;s dependencies.&lt;br /&gt;
I use &amp;quot;may&amp;quot;, because it seems that &lt;code&gt;dotenv&lt;/code&gt; features are wider than the native
&lt;code&gt;--env-file&lt;/code&gt; so beware if you have a sophisticated usage of the &lt;code&gt;dotenv&lt;/code&gt;
library.&lt;/p&gt;
&lt;p&gt;According to Node.js&#39; documentation, &lt;code&gt;--env-file&lt;/code&gt; argument...&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;loads environment variables from a file relative to the current directory,
making them available to applications on &lt;code&gt;process.env&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://nodejs.org/dist/latest-v22.x/docs/api/cli.html#environment-variables&quot;&gt;environment variables which configure Node.js&lt;/a&gt;, such as &lt;code&gt;NODE_OPTIONS&lt;/code&gt;,
are parsed and applied.&lt;br /&gt;
If the same variable is defined in the environment and in the file, the value
from the environment takes precedence.&lt;/p&gt;
&lt;p&gt;You can pass multiple &lt;code&gt;--env-file&lt;/code&gt; arguments. Subsequent files override
pre-existing variables defined in previous files.An error is thrown if the
file does not exist.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here is an example command, using multiple &lt;code&gt;--env-file&lt;/code&gt; arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;node --env-file=.env --env-file=.development.env index.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;--env-file-if-exists&lt;/code&gt; flag superclass &lt;code&gt;--env-file&lt;/code&gt; in the sense that it
first checks for file existence.&lt;/p&gt;
</description>
       <pubDate>Tue, 01 Apr 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-use-env-files-natively-with-nodejs/</guid>
    </item>
    <item>
       <title>Today I learned: How to access an array item in a Handlebars template</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-access-an-array-item-in-a-handlebars-template/</link>
       <description>&lt;p&gt;To access an item of an array outside of a &lt;code&gt;each&lt;/code&gt; block helper, for
instance, may not be as a straightforward guess for JavaScript developers, as
the notation is a little bit odd.&lt;/p&gt;
&lt;p&gt;Taken the context data of:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;{
  supportFolks: [
    {
      fullname: &#39;John Doe&#39;,
    },
    {
      fullname: &#39;Clark Kent&#39;
    }
  ],
  fullnames: [
    &#39;John Doe&#39;,
    &#39;Clark Kent&#39;
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can access the &lt;code&gt;supportFolks&lt;/code&gt; array items individually as below:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-handlebars&quot;&gt;Monday colleague on support is {{supportFolks.[0].fullname}}
Tuesday colleague on support is {{supportFolks.[1].fullname}}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;what is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-handlebars&quot;&gt;Monday colleague on support is {{supportFolks.0.fullname}}
Tuesday colleague on support is {{supportFolks.1.fullname}}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Beware though with the ladder. Indeed, if the entry is a non-object
value, you cannot just call &lt;code&gt;fullnames.0&lt;/code&gt; and expect it to work. You would
have to go with &lt;code&gt;fullnames.[0]&lt;/code&gt;.&lt;br /&gt;
For that reason I would &lt;strong&gt;not recommend&lt;/strong&gt; using the non-square-bracket
expression as this may lead to confusions down the line.&lt;/p&gt;
</description>
       <pubDate>Mon, 31 Mar 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-access-an-array-item-in-a-handlebars-template/</guid>
    </item>
    <item>
       <title>You may not need Vim relativenumber option after all</title>
       <link>https://morgan.cugerone.com/blog/you-may-not-need-vim-relative-line-numbers/</link>
       <description>&lt;h2&gt;Notice&lt;/h2&gt;
&lt;p&gt;Vim &lt;strong&gt;relativenumber&lt;/strong&gt; option is very popular and admittedly very seducing. So I
believe this post may be controversial although this is absolutely not its
intent. So please approach it with an open mind, thank you.&lt;/p&gt;
&lt;h2&gt;What is Vim &lt;em&gt;relativenumber&lt;/em&gt; option&lt;/h2&gt;
&lt;p&gt;According to Vim&#39;s help, &lt;strong&gt;relativenumber&lt;/strong&gt; option:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Show the line number relative to the line with the cursor in front of each
line. Relative line numbers help you use the |count| you can precede some
vertical motion commands (e.g. &lt;kbd&gt;j&lt;/kbd&gt;, &lt;kbd&gt;k&lt;/kbd&gt;, &lt;kbd&gt;+&lt;/kbd&gt;,
&lt;kbd&gt;-&lt;/kbd&gt;) with, without having to calculate it
yourself. Especially useful in combination with other commands (e.g.
&lt;kbd&gt;y&lt;/kbd&gt;, &lt;kbd&gt;d&lt;/kbd&gt;, &lt;kbd&gt;c&lt;/kbd&gt;, &lt;kbd&gt;&amp;lt;&lt;/kbd&gt;, &lt;kbd&gt;&amp;gt;&lt;/kbd&gt;,
&lt;kbd&gt;gq&lt;/kbd&gt;, &lt;kbd&gt;gw&lt;/kbd&gt;, &lt;kbd&gt;=&lt;/kbd&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As I before told, this sounds very seducing!&lt;/p&gt;
&lt;h2&gt;Drawback&lt;/h2&gt;
&lt;p&gt;So where is the bitter in this sweet nifty feature you would ask?&lt;/p&gt;
&lt;p&gt;Firstly, looking at the margin, i.e in front of each line, to get a number to
inform your vertical movements may be a form of distraction almost as big as
grabbing your mouse to move the cursor.&lt;/p&gt;
&lt;p&gt;Secondly, vertical motion commands used in combination with the &lt;em&gt;relativenumber&lt;/em&gt;
do not qualifies as Vim jumps and therefore do not feed the Vim &lt;strong&gt;jump
list&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;According to Vim&#39;s help, a &lt;em&gt;jump&lt;/em&gt; is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A command that normally moves the cursor several lines away.&lt;br /&gt;
If you make the cursor &amp;quot;jump&amp;quot;, the position of the cursor before the jump is
remembered. You can return to that position with the &lt;kbd&gt;&#39;&#39;&lt;/kbd&gt;
and &lt;kbd&gt;``&lt;/kbd&gt; commands, unless the line containing that position was
changed or deleted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;kbd&gt;&#39;&#39;&lt;/kbd&gt; and &lt;kbd&gt;``&lt;/kbd&gt; commands only let you
move back and forth between last and current position, but to navigate beyond
these 2 positions in the jump list the &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;o&lt;/kbd&gt; and
&lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;i&lt;/kbd&gt; commands exists to navigate respectively backward
and forward through the list.
Convenient isn&#39;t it?&lt;/p&gt;
&lt;p&gt;Once this convenience mapped into your muscle memory you are up to some very
efficient Vim editing experience. I though agree this requires practice, but as
most of things in Vim.&lt;/p&gt;
&lt;p&gt;Using &lt;em&gt;relativenumber&lt;/em&gt; option, you miss the opportunity to benefit from this Vim
convenience and key feature.&lt;/p&gt;
&lt;p&gt;Finally, if you happen to do some pair-programming, &lt;em&gt;relativenumber&lt;/em&gt; can reveal
super disorienting for your pair when the line numbers in the margin keep
updating as you are moving the cursor vertically.&lt;br /&gt;
You may end up turning off the option, but you are then left with absolute line
number and feel hindered because you mapped your brain and muscle memory to use
relative line number.&lt;/p&gt;
&lt;h2&gt;What should you do/learn doing instead?&lt;/h2&gt;
&lt;h3&gt;Populate and navigate the jump list&lt;/h3&gt;
&lt;p&gt;At this point you may have understood that you should favour using Vim vertical
motion commands that qualifies as jumps and therefore populate the jump
list.&lt;br /&gt;
Remember this has the added benefit that you can navigate these jumps with
&lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;o&lt;/kbd&gt; and &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;i&lt;/kbd&gt; motion
commands that respectively jump backward and forward the jump list.&lt;/p&gt;
&lt;p&gt;Now you may be asking what are these qualifying commands?&lt;/p&gt;
&lt;p&gt;Here is the list, with some attempt to provide a useful description of what they
do:&lt;/p&gt;
&lt;p&gt;Note that there are mentions of Vim marks below and that we will expand on these
in the next section.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;&#39;x&lt;/kbd&gt;: Jumps to line of Vim mark &lt;em&gt;x&lt;/em&gt;;  &lt;em&gt;x&lt;/em&gt; being any
character to be used as marks&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;`x&lt;/kbd&gt;: Jumps to position (line and column) of Vim mark
&lt;em&gt;x&lt;/em&gt;;  &lt;em&gt;x&lt;/em&gt; being any character to be used as marks&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;G&lt;/kbd&gt;: Jumps to the last line of the current buffer&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;nG&lt;/kbd&gt;: Jumps to the nth line of the current buffer&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;/foo&lt;/kbd&gt;: Jumps to first forward match of &amp;quot;foo&amp;quot; pattern&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;?foo&lt;/kbd&gt;: Jumps to first backward match of &amp;quot;foo&amp;quot; pattern&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;n&lt;/kbd&gt; and &lt;kbd&gt;N&lt;/kbd&gt;: Jumps to next and previous match of the work
under the cursor&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;%&lt;/kbd&gt;: Jumps to pairing item of a pair (i.e. &lt;em&gt;{}&lt;/em&gt;, &lt;em&gt;()&lt;/em&gt;...)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;(&lt;/kbd&gt; and &lt;kbd&gt;)&lt;/kbd&gt;: Jumps backward and forward through sentences&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;{&lt;/kbd&gt; and &lt;kbd&gt;}&lt;/kbd&gt;: Jumps backward and forward through paragraphs&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;:s&lt;/kbd&gt;: Jumps to the last location of a substitute command&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;:tag myTag&lt;/kbd&gt;: Jump to the definition of &amp;quot;myTag&amp;quot; tag&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;H&lt;/kbd&gt;: Jumps to the Highest (i.e first) line of the window&#39;s visible
text&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;nH&lt;/kbd&gt;: Jumps to the nth line from the top of the window&#39;s visible text&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;M&lt;/kbd&gt;: Jumps to the line in the Middle of the window&#39;s visible text&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;L&lt;/kbd&gt;: Jumps to the Last (i.e bottom) line of the window&#39;s visible text&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;nL&lt;/kbd&gt;: Jumps to the nth line from the bottom of the window&#39;s visible
text&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;[[&lt;/kbd&gt;: Jumps to the previous section (i.e previous opening curly brace
in the first columns)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;]]&lt;/kbd&gt;: Jumps to the next section (i.e next opening curly brace in the
first columns)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Beware, &lt;kbd&gt;]]&lt;/kbd&gt; and &lt;kbd&gt;[[&lt;/kbd&gt; keymaps can be overridden by plugins and not
count as jumps (e.g. with &lt;em&gt;nvim-markdown&lt;/em&gt; plugin, and therefore in Markdown
files).&lt;/p&gt;
&lt;p&gt;Another field of possibilities offers to you if you consider Vim plugins.
Indeed, there are some kind enough to maintain the jump list for you.&lt;/p&gt;
&lt;p&gt;For instance &lt;em&gt;telescope.nvim&lt;/em&gt;&#39;s &lt;code&gt;builtin.current_buffer_fuzzy_find&lt;/code&gt; function,
that you can use to fuzzy search terms within a Vim buffer.&lt;br /&gt;
Indeed, if you jump to the match, it updates the jump list accordingly, and
therefore if you use &lt;kbd&gt;&#39;&#39;&lt;/kbd&gt;, &lt;kbd&gt;``&lt;/kbd&gt; or  &lt;kbd&gt;Ctrl&lt;/kbd&gt; +
&lt;kbd&gt;o&lt;/kbd&gt;, motion commands, it jumps back to the position the cursor was
prior to the search. Nifty!&lt;/p&gt;
&lt;h3&gt;Use the &lt;em&gt;change list&lt;/em&gt; commands&lt;/h3&gt;
&lt;p&gt;According to Vim&#39;s help:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When making a change the cursor position is remembered. Two commands can be
used to jump to positions of changes...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;g;&lt;/kbd&gt;: Jumps to position of last change&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;g,&lt;/kbd&gt;: Jumps to position of next change&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is yet another convenient feature to learn to master.&lt;/p&gt;
&lt;h3&gt;Use Vim marks commands&lt;/h3&gt;
&lt;p&gt;If you are not familiar to Vim marks I would highly recommend to have a read
through &lt;a href=&quot;https://vim.fandom.com/wiki/Using_marks&quot;&gt;Vim Fandom&#39;s &amp;quot;Using marks&amp;quot; entry&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Assuming you are now familiar to these, let&#39;s dig in and see what is in this for
you to move away from using Vim &lt;em&gt;relativenumber&lt;/em&gt; option.&lt;/p&gt;
&lt;p&gt;It is possible to navigate between lowercase marks, a.k.a local (to current
buffer) marks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;]&#39;&lt;/kbd&gt;: Jumps to next line with a lowercase mark&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;[&#39;&lt;/kbd&gt;: Jumps to previous line with a lowercase mark&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;]`&lt;/kbd&gt;: Jumps to next lowercase mark position (line and column)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;[`&lt;/kbd&gt;: Jumps to previous lowercase mark position (line and column)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above commands take a count. For example, &lt;kbd&gt;5]`&lt;/kbd&gt; jumps to the fifth
mark after the cursor. This may be mentally taxing, so use this only if you are
well equipped to carry this overhead.&lt;/p&gt;
&lt;p&gt;Some more useful Vim marks commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;`.&lt;/kbd&gt;: Jumps to position where last change occurred in current buffer&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;&#39;&#39;&lt;/kbd&gt;: Jumps back (to line in current buffer where jumped from)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;``&lt;/kbd&gt;: Jumps back (to position in current buffer where jumped from)&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;`[&lt;/kbd&gt;: Jumps to the beginning of previously changed or yanked text&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;`]&lt;/kbd&gt;: Jumps to the end of previously changed or yanked text&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;`&amp;lt;&lt;/kbd&gt;: Jumps to the beginning of last visual selection&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;`&amp;gt;&lt;/kbd&gt;: Jumps to the end of last visual selection&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Practical use of Vim marks&lt;/h4&gt;
&lt;p&gt;Here are 2 valuable hints I distilled from this great &lt;a href=&quot;https://jitesh117.github.io/vim_stuff/use-marks-and-jumps-effectively-in-vim/#practical-uses-of-marks&quot;&gt;&amp;quot;Practical uses of
marks&amp;quot; blog post&lt;/a&gt; that you may also find supportive.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Marking important sections (e.g. configuration section, reference links
section, key sections of code to jump back and forth from/to)&lt;/li&gt;
&lt;li&gt;Copying between distant parts of a file by setting a mark at the source (e.g.
&lt;kbd&gt;ms&lt;/kbd&gt;), then moving to the destination and yanking from the mark (e.g.
&lt;kbd&gt;y`s&lt;/kbd&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Capitalise on your learnings by combining marks and jumps beyond the edges of your current buffer&lt;/h2&gt;
&lt;p&gt;Once again distilled from the great &lt;a href=&quot;https://jitesh117.github.io/vim_stuff/use-marks-and-jumps-effectively-in-vim/#practical-uses-of-marks&quot;&gt;&amp;quot;Practical uses of marks&amp;quot; blog post&lt;/a&gt; and
applicable beyond the scope of your current buffer, here are 3 nifty tips:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Set marks at key points in your workflow&lt;/strong&gt;, then use jumps to navigate
between these points and other parts of your file or project.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use uppercase marks to jump between files&lt;/strong&gt;, and then use
&lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;o&lt;/kbd&gt; to return to your previous position.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create a &amp;quot;breadcrumb trail&amp;quot;&lt;/strong&gt; through your code by setting sequential marks
(e.g., &lt;kbd&gt;ma&lt;/kbd&gt;, &lt;kbd&gt;mb&lt;/kbd&gt;, &lt;kbd&gt;mc&lt;/kbd&gt;) and then use jumps to move
along this trail.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Diving myself into the research to alternative options to using Vim&#39;s
&lt;strong&gt;relativenumber&lt;/strong&gt; option I came across a myriad of options and opportunities to
forge, I think, a more efficient Vim editing experience.&lt;/p&gt;
&lt;p&gt;I am at the starting point of this learning journey and very excited by the
field of possibilities.&lt;/p&gt;
&lt;p&gt;I hope this excitement and opportunity to become more efficient propagates to
you, or that you at least pick up a few Vim tricks you did not know about along
the way.&lt;/p&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Vim&#39;s help (from within Vim &lt;kbd&gt;:help searchTerm&lt;/kbd&gt;, e.g
&lt;kbd&gt;:help jumps&lt;/kbd&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vim.fandom.com/wiki/Using_marks&quot;&gt;Vim Fandom&#39;s &amp;quot;Using marks&amp;quot; entry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jitesh117.github.io/vim_stuff/use-marks-and-jumps-effectively-in-vim/#practical-uses-of-marks&quot;&gt;&amp;quot;Practical uses of marks&amp;quot; blog post&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Fri, 28 Mar 2025 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/you-may-not-need-vim-relative-line-numbers/</guid>
    </item>
    <item>
       <title>How to open Firefox Developer Edition from the command line on Mac OS</title>
       <link>https://morgan.cugerone.com/blog/how-to-open-firefox-developer-edition-from-command-line-on-mac-os/</link>
       <description>&lt;p&gt;As this took me some Duck Duck Going to figure out how to open Firefox Developer
Edition from the command line, I felt I needed to share it here.&lt;/p&gt;
&lt;p&gt;Hopefully it will now high rank in search engines results for the next one doing
the search (it could be my future self!).&lt;/p&gt;
&lt;p&gt;Without further ado, here it is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;open -a &amp;quot;Firefox Developer Edition&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Swap, &lt;code&gt;Firefox Developer Edition&lt;/code&gt; with any other browsers name (e.g. &lt;code&gt;Safari&lt;/code&gt;,
&lt;code&gt;Firefox&lt;/code&gt;, &lt;code&gt;Chrome&lt;/code&gt;, &lt;code&gt;Brave&lt;/code&gt;?) and that should do, I assume.&lt;/p&gt;
&lt;p&gt;Add the site or the file name you desire to open as the following argument and
it may open it directly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;open -a &amp;quot;Firefox Developer Edition&amp;quot; http://www.duckduckgo.com

open -a &amp;quot;Firefox Developer Edition&amp;quot; index.html
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s all folks! Cheers!&lt;/p&gt;
</description>
       <pubDate>Fri, 30 Sep 2022 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-open-firefox-developer-edition-from-command-line-on-mac-os/</guid>
    </item>
    <item>
       <title>My testing with Jest takeaways</title>
       <link>https://morgan.cugerone.com/blog/my-testing-with-jest-takeaways/</link>
       <description>&lt;h2&gt;Takeaways&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Test files (i.e suites) are run in parallel unless you use the &lt;code&gt;--runInBand&lt;/code&gt;
(in short &lt;code&gt;-i&lt;/code&gt;) option.&lt;/li&gt;
&lt;li&gt;Tests within a file are always run sequentially (in series).&lt;/li&gt;
&lt;li&gt;A tests file is first parsed to collect tests, this is the collection phase.&lt;/li&gt;
&lt;li&gt;Tests are run in the order they were collected.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;describe&lt;/code&gt; is a good mean to organise the code &lt;strong&gt;BUT&lt;/strong&gt; also influences the
scope of the setup/teardown functions like &lt;code&gt;beforeAll()&lt;/code&gt;, &lt;code&gt;beforeEach()&lt;/code&gt;,
&lt;code&gt;afterAll()&lt;/code&gt;, &lt;code&gt;afterEach()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In a &lt;code&gt;describe&lt;/code&gt;, &lt;code&gt;beforeAll()&lt;/code&gt; and &lt;code&gt;afterAll()&lt;/code&gt; are executed respectively
before and after &lt;strong&gt;ALL&lt;/strong&gt; of the tests collected from this &lt;code&gt;describe&lt;/code&gt; block
and all its nested &lt;code&gt;describe&lt;/code&gt; blocks.&lt;/li&gt;
&lt;li&gt;In a &lt;code&gt;describe&lt;/code&gt;, &lt;code&gt;beforeEach()&lt;/code&gt; and &lt;code&gt;afterEach()&lt;/code&gt; are executed respectively
before and after &lt;strong&gt;EACH&lt;/strong&gt; of the tests collected from this describe block and
all its nested &lt;code&gt;describe&lt;/code&gt; blocks.&lt;/li&gt;
&lt;li&gt;BEWARE, any code line inside of &lt;code&gt;describe&lt;/code&gt; that is not part of a
setup/teardown function nor a test (aka &lt;code&gt;it&lt;/code&gt;) block, is executed during the
collection phase, so avoid instructions for cleaning in there as they will be
executed before the first test is run, what may not be of your intent&lt;/li&gt;
&lt;li&gt;There is &lt;strong&gt;ONE&lt;/strong&gt; instance of a global variable per Test file (e.g one JSDOM
instance), shared across all the tests within the tests file.&lt;/li&gt;
&lt;li&gt;Same goes with a mocked module, so make sure that you call your reset
functions such as &lt;code&gt;mockClear()&lt;/code&gt;, &lt;code&gt;mockReset()&lt;/code&gt; either in a setup/teardown
function or at top/end of each tests if you prefer that style&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jestjs.io/docs/setup-teardown&quot;&gt;Setup and Teardown on Jest documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cmdcolin.github.io/posts/2021-10-05-jest&quot;&gt;Jest parallelization, globals, mocks, and squawkless tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Sun, 29 May 2022 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/my-testing-with-jest-takeaways/</guid>
    </item>
    <item>
       <title>CSS Media queries media types and features cheatsheet</title>
       <link>https://morgan.cugerone.com/blog/css-media-queries-media-types-and-features-cheatsheet/</link>
       <description>&lt;h2&gt;Media types&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@media#media_types&quot;&gt;Reference page for media types&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;all&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;print&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;screen&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Media features&lt;/h2&gt;
&lt;h3&gt;Standard media features&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@media#media_features&quot;&gt;Reference page for standard media features&lt;/a&gt; (worth while clicking because some are new or deprecated…)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;any-hover&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;any-pointer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aspect-ratio&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;color&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;color-gamut&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;color-index&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;device-aspect-ratio&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;device-height&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;device-width&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;display-mode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;forced-colors&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grid&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;height&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hover&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;inverted-colors&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;monochrome&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;orientation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;overflow-block&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;overflow-inline&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pointer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prefers-color-scheme&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prefers-contrast&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prefers-reduced-motion&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;resolution&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scripting&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;width&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Microsoft Media features:&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Microsoft_Extensions#media_features&quot;&gt;Reference page for Microsoft media features&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-ms-high-contrast&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Mozilla Media features:&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Mozilla_Extensions#media_features&quot;&gt;Reference page for Mozilla media features&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-moz-device-pixel-ratio&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-moz-os-version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-moz-touch-enabled&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-moz-windows-glass&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Webkit Media features:&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions#media_features&quot;&gt;Reference page for Webkit media features&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-webkit-animation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-webkit-device-pixel-ratio&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-webkit-transform-2d&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-webkit-transform-3d&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-webkit-transition&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Other resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/TR/css3-mediaqueries/#media1&quot;&gt;Media queries level 3 specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://drafts.csswg.org/mediaqueries/#media&quot;&gt;Media queries level 4 draft specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Fall-Back/CSS-Mustard-Cut&quot;&gt;CSS Only Mustard Cut, useful to build queries to target set of browsers leveraging CSS Media queries&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Fri, 21 Jan 2022 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/css-media-queries-media-types-and-features-cheatsheet/</guid>
    </item>
    <item>
       <title>Workarounds to Git worktree using bare repository and cannot fetch remote branches</title>
       <link>https://morgan.cugerone.com/blog/workarounds-to-git-worktree-using-bare-repository-and-cannot-fetch-remote-branches/</link>
       <description>&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;This post echoes to an inefficiency I faced after adding Git worktrees to my
workflow in the manner described in &lt;a href=&quot;https://morgan.cugerone.com/blog/how-to-use-git-worktree-and-in-a-clean-way/&quot;&gt;How to use git worktree and in a clean
way&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The issue&lt;/h2&gt;
&lt;p&gt;After a while using git worktrees and willing to add a worktree based upon a
remote branch from &lt;code&gt;origin&lt;/code&gt;, I discovered that I just could not.&lt;br /&gt;
It was very frustrating.&lt;br /&gt;
A bit of googling helped me to identify the root cause.&lt;/p&gt;
&lt;h2&gt;The root cause&lt;/h2&gt;
&lt;p&gt;The root cause, does not come down to the use of Git worktrees, but rather to
the way I use them.&lt;/p&gt;
&lt;p&gt;Indeed, I use Git worktrees in combination of bare repositories.&lt;/p&gt;
&lt;p&gt;I discovered, as described in the &lt;a href=&quot;https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---bare&quot;&gt;Git documentation about making a
bare
repository&lt;/a&gt;,
that when using &lt;code&gt;git clone&lt;/code&gt; with the &lt;code&gt;--bare&lt;/code&gt; option:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;neither remote-tracking branches nor the related configuration variables are
created.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That basically means that when you try to &lt;code&gt;git fetch&lt;/code&gt; from your remote (e.g
&lt;code&gt;origin&lt;/code&gt;), the remote branches are not downloaded.&lt;br /&gt;
The reason for this is that the configuration of the repository does not get
populated with the &lt;code&gt;remote.origin.fetch&lt;/code&gt; property at the clone operation.&lt;/p&gt;
&lt;h2&gt;A short-term workaround&lt;/h2&gt;
&lt;p&gt;In the repository&#39;s directory, open up your &lt;code&gt;$GIT_DIR/config&lt;/code&gt; file (e.g.
&lt;code&gt;.git/config&lt;/code&gt; or in my case &lt;code&gt;.bare/config&lt;/code&gt;) and add a new line under &lt;code&gt;[remote &amp;quot;origin&amp;quot;]&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fetch = +refs/heads/*:refs/remotes/origin/*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the event you do not fancy editing manually the configuration file you can
also run the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config remote.origin.fetch &amp;quot;+refs/heads/*:refs/remotes/origin/*&amp;quot; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Below is an excerpt of the configuration file with the &lt;code&gt;remote.origin.fetch&lt;/code&gt;
property correctly configured:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[remote &amp;quot;origin&amp;quot;]
    url = …
    fetch = +refs/heads/*:refs/remotes/origin/*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, any &lt;code&gt;git fetch origin&lt;/code&gt; or &lt;code&gt;git worktree add...&lt;/code&gt; command will, when
necessary, retrieves the remote branches that are missing locally.&lt;/p&gt;
&lt;h2&gt;My long-term workaround&lt;/h2&gt;
&lt;p&gt;As much as I was happy with the short-term workaround I wanted to save me the
hassle of this manual step when cloning a new repository into a bare one.&lt;/p&gt;
&lt;p&gt;Therefore I came up with a script that I use when cloning repositories for use
with git worktree.&lt;/p&gt;
&lt;p&gt;Actually not only, it does the work of making the &lt;code&gt;$GIT_DIR&lt;/code&gt; how I
want it (i.e in &lt;code&gt;.bare&lt;/code&gt;), it does also the under laying work of setting the
&lt;code&gt;remote.origin.fetch&lt;/code&gt; property into the newly created bare repository and
fetches all remote branches.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash
set -e

# Examples of call:
# git-clone-bare-for-worktrees git@github.com:name/repo.git
# =&amp;gt; Clones to a /repo directory
#
# git-clone-bare-for-worktrees git@github.com:name/repo.git my-repo
# =&amp;gt; Clones to a /my-repo directory

url=$1
basename=${url##*/}
name=${2:-${basename%.*}}

mkdir $name
cd &amp;quot;$name&amp;quot;

# Moves all the administrative git files (a.k.a $GIT_DIR) under .bare directory.
#
# Plan is to create worktrees as siblings of this directory.
# Example targeted structure:
# .bare
# main
# new-awesome-feature
# hotfix-bug-12
# ...
git clone --bare &amp;quot;$url&amp;quot; .bare
echo &amp;quot;gitdir: ./.bare&amp;quot; &amp;gt; .git

# Explicitly sets the remote origin fetch so we can fetch remote branches
git config remote.origin.fetch &amp;quot;+refs/heads/*:refs/remotes/origin/*&amp;quot;

# Gets all branches from origin
git fetch origin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have even been one step further by binding this script to a git alias as
shown in below &lt;code&gt;.gitconfig&lt;/code&gt; file excerpt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[alias]
	clone-for-worktrees = &amp;quot;!sh $HOME/git-clone-bare-for-worktrees.sh&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thus I can run &lt;code&gt;git clone-for-worktrees git@github.com:name/my-awesome-project.git&lt;/code&gt;
and be all set for using the &lt;code&gt;my-awesome-project&lt;/code&gt; with git worktrees.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That&#39;s all folks.&lt;br /&gt;
No matter which solution you pick, as long as it lets you persist using git
worktrees I&#39;m happy. There are an awesome feature from git!&lt;/p&gt;
</description>
       <pubDate>Fri, 14 Jan 2022 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/workarounds-to-git-worktree-using-bare-repository-and-cannot-fetch-remote-branches/</guid>
    </item>
    <item>
       <title>How to fail fast your shell script</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-to-fail-fast-your-shell-scripts/</link>
       <description>&lt;p&gt;A couple of weeks ago I came across the scenario in which although my build
scripts was having linting issues, the pipeline running this script would not
fail.&lt;/p&gt;
&lt;p&gt;My investigation led me to stumble upon a nice combo of shell commands that
would ensure the script to fail fast and avoid having non desired outcomes.&lt;/p&gt;
&lt;h2&gt;A neat commands combo to fail fast&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;set -o errexit
set -o errtrace
set -o nounset
set -o pipefail
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In short this should exit as soon as it encounters any non-zero exit code or
usage of undefined variables or failed piped commands.&lt;/p&gt;
&lt;p&gt;The one-liner command of the previous combo is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set -Eeuo pipefail
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Having this combo in my shell scripts make them safer and therefore increases my
confidence when pushing a change.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/&quot;&gt;Safer bash scripts with &#39;set -euxo
pipefail&#39;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html&quot;&gt;The Set
Builtin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Fri, 12 Nov 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-to-fail-fast-your-shell-scripts/</guid>
    </item>
    <item>
       <title>How to catch errors as soon as they occur in bash scripts</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-catch-errors-as-soon-as-they-occur-in-bash-scripts/</link>
       <description>&lt;p&gt;Let me introduce you to the power trio you will want to add to your bash scripts
in order to fail fast upon error and avoid the script to continue despite the
error.&lt;/p&gt;
&lt;h2&gt;Power trio&lt;/h2&gt;
&lt;p&gt;By trio I mean the 3 &lt;code&gt;set&lt;/code&gt; builtins to be found in the below code snippet.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail

# Some example commands
npm ci

npm run build
npm run lint
# ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is a run down of what they aim at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;set -o errexit&lt;/code&gt; (short version: &lt;code&gt;set -e&lt;/code&gt;): Exits immediately upon non-zero
status.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;set -o nounset&lt;/code&gt; (short version: &lt;code&gt;set -u&lt;/code&gt;): Exits immediately upon usage of
undefined variables.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;set -o pipefail&lt;/code&gt;: Exits immediately upon failed piped commands.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html&quot;&gt;The set builtin&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://betterprogramming.pub/best-practices-for-bash-scripts-17229889774d&quot;&gt;Best Practices for Bash Scripts&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Wed, 13 Oct 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-catch-errors-as-soon-as-they-occur-in-bash-scripts/</guid>
    </item>
    <item>
       <title>Today I learned: How to assert the new active element after Tab keydown event in Jest</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-assert-active-element-after-tab-keydown-event-in-jest/</link>
       <description>&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;Today I was writing a test that would assert that by using the Tab key onto the
button of a component, the focus will move to the next focusable element.&lt;/p&gt;
&lt;p&gt;The test was failing, although the expected behaviour was to be seen in the
browser.&lt;/p&gt;
&lt;h2&gt;Failing test&lt;/h2&gt;
&lt;p&gt;Below &lt;code&gt;createKeydownEvent&lt;/code&gt; is a custom utility function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;it(&#39;once focused on the button, it can be tabbed away&#39;, () =&amp;gt; {
	// ...
	const keydownTabEvent = createKeydownEvent(&#39;Tab&#39;);
	const button = component.querySelector(&#39;button&#39;);
	const nextInteractiveElement = document.querySelector(&#39;a&#39;);
	button.focus();

	expect(document.activeElement).toBe(button);

	button.dispatchEvent(keydownTabEvent);

	expect(document.activeElement).toBe(nextInteractiveElement);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;expect&lt;/code&gt; fails because the expected &lt;code&gt;document.activeElement&lt;/code&gt; happens to be
the button, as if the Tab &lt;code&gt;keydown&lt;/code&gt; event has no effect what so ever.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;After some intense debugging, googling and reaching out to colleagues I came
down to this conclusion:&lt;/p&gt;
&lt;p&gt;When an element looses focus, the next element to acquire it actually gets it on
the next tick of the &lt;a href=&quot;https://www.youtube.com/watch?v=8aGhZQkoFbQ&quot;&gt;event loop&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Calling &lt;code&gt;setTimeout(callback, 0)&lt;/code&gt;, where &lt;code&gt;callback&lt;/code&gt; does the assertion, would
execute its callback at the end of the next tick i.e. when the next element
acquires the focus.&lt;/p&gt;
&lt;p&gt;Equiped with this knowledge I could fix the failing test by wrapping the
assertion into a &lt;code&gt;setTimeout(callback, 0)&lt;/code&gt; call as show below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setTimeout(() =&amp;gt; {
	expect(document.activeElement).toBe(nextInteractiveElement);
}, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://nodejs.dev/learn/understanding-process-nexttick&quot;&gt;Understanding process.nextTick()&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Tue, 12 Oct 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-assert-active-element-after-tab-keydown-event-in-jest/</guid>
    </item>
    <item>
       <title>&#39;source: not found&#39; in the context of npm scripts</title>
       <link>https://morgan.cugerone.com/blog/troubleshooting-source-not-found-when-in-the-context-of-package-json-scripts/</link>
       <description>&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;Today at work I found out that the following script from the &lt;code&gt;scripts&lt;/code&gt; section
of our &lt;code&gt;package.json&lt;/code&gt; was not working on my colleague&#39;s machine. He is running
Ubuntu. I have seen this happening also on the Arch distribution.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;start:dev&amp;quot;: &amp;quot;source .env; nodemon index.js&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This script aims at sourcing a bunch of environement variables and then only
running the application.&lt;/p&gt;
&lt;p&gt;This had worked under OSX since the beginning of the project though.&lt;/p&gt;
&lt;h2&gt;What is happening&lt;/h2&gt;
&lt;p&gt;Basically, if not specified as a &lt;code&gt;npm&lt;/code&gt; config, &lt;code&gt;npm-run&lt;/code&gt; uses the system&#39;s
default &lt;code&gt;/bin/sh&lt;/code&gt; as shell to execute commands in script entries.&lt;br /&gt;
This means that if your system is using a default shell that does not implement
the &lt;code&gt;source&lt;/code&gt; command, you are getting this &lt;code&gt;source: not found&lt;/code&gt; error.&lt;/p&gt;
&lt;p&gt;But &lt;code&gt;npm&lt;/code&gt; gets you covered 😅&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;The solution is to specify the &lt;code&gt;npm&lt;/code&gt;&#39;s &lt;code&gt;script-shell&lt;/code&gt; config, before running the
&lt;code&gt;source&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;The script entry presented in the context section above would become:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;start:dev&amp;quot;: &amp;quot;npm config set script-shell &#92;&amp;quot;/bin/bash&#92;&amp;quot;; source .env; nodemon index.js&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is a bit wordy but does usually get you out of trouble as long as the system
running the command implements &lt;code&gt;bash&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.npmjs.com/cli/v6/using-npm/config#script-shell&quot;&gt;script-shell on NPM
documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://askubuntu.com/a/1334710&quot;&gt;Bash source + npm script function not exported but variable is | Ask Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Fri, 17 Sep 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/troubleshooting-source-not-found-when-in-the-context-of-package-json-scripts/</guid>
    </item>
    <item>
       <title>How to test a basic (No JavaScript) experience in Testcafé</title>
       <link>https://morgan.cugerone.com/blog/how-to-test-a-no-javascript-experience-in-testcafe/</link>
       <description>&lt;p&gt;I am relatively new to &lt;a href=&quot;https://testcafe.io/&quot;&gt;Testcafé testing framework&lt;/a&gt; that
claims for:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;End-to-end testing, simplified
No WebDriver required. No manual timeouts needed.
Cross-browser testing out-of-the-box.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I must admit the syntax is a bit confusing at first, but you get quickly up to
speed, thanks to useful documentation, what is quite rewarding.&lt;/p&gt;
&lt;h2&gt;Progressive enhancement&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://morgan.cugerone.com/tags/progressive-enhancement/&quot;&gt;I do care a great deal about Progressive
enhancement&lt;/a&gt;. This is my go to approach to build
components and experiences for the web.&lt;br /&gt;
First deliver a basic experience that works without JavaScript, and then second,
if JavaScript is available and if the browser in use can support the
enhancement, deliver the enhanced experience.&lt;/p&gt;
&lt;p&gt;If you are doing Agile developement, this fits perfectly as you could first ship
a basic working experience and in the next iteration the enhanced experience.&lt;/p&gt;
&lt;h2&gt;What I needed&lt;/h2&gt;
&lt;p&gt;In order to gain confidence upon the fact that both my basic and enhanced
experiences are working, I needed to be able to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Test the &lt;strong&gt;basic experience&lt;/strong&gt; when the JavaScript that enhances my component
is &lt;strong&gt;unavailable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Test the &lt;strong&gt;enhanced experience&lt;/strong&gt; when the JavaScript that enhances my
component is &lt;strong&gt;available&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We, from the Testcafé configuration, have no such thing as an option to disable
JavaScript, and most especially because Testcafé runs using JavaScript in the
browser that drives the test.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: For this solution to work, the JavaScript holding the code
necessary for the enhancement should be an external file.&lt;br /&gt;
Why? Because the hack is to fake that the JavaScript file is &lt;code&gt;Not found&lt;/code&gt;,
resolving to a &lt;code&gt;404&lt;/code&gt; status code.&lt;/p&gt;
&lt;p&gt;To perform this lie, we can use &lt;a href=&quot;https://testcafe.io/documentation/402667/reference/test-api/requestmock&quot;&gt;Testcafé Request Mock
feature&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A request mocker that intercepts requests to a web resource and emulates the
response.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The small code snippet below led me to success:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const turnOfJavaScriptMock = RequestMock()
    .onRequestTo(new RegExp(&#39;.*&#92;.js&#39;))
    .respond(null, 404);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is how you instanciate the mock to make any requested &lt;code&gt;.js&lt;/code&gt; file in the
page under test to respond with a &lt;code&gt;404 Not Found&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now you can use this mock in your tests as below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;test
	.page `URL-OF-PAGE-UNDER-TEST`
(`Enter your test label here for the enhanced experience`, async t =&amp;gt; {
	// Add your assertions here
});

test
	.page `URL-OF-PAGE-UNDER-TEST`
	.requestHooks(turnOfJavaScriptMock)
(`Enter your test label here for the basic experience`, async t =&amp;gt; {
	// Add your assertions here
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The magic operates through the call to &lt;code&gt;.requestHooks()&lt;/code&gt; function that takes our
Request Mock as argument and applies it the page under test.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Using a very concise Request Mock that turns off any external JavaScript we are
able to end-to-end test the fall back experience of our enhanced experience, i.e
the basic experience 😉.&lt;/p&gt;
</description>
       <pubDate>Wed, 15 Sep 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-test-a-no-javascript-experience-in-testcafe/</guid>
    </item>
    <item>
       <title>How to use git worktree and in a clean way</title>
       <link>https://morgan.cugerone.com/blog/how-to-use-git-worktree-and-in-a-clean-way/</link>
       <description>&lt;h2&gt;A bit of vocabulary&lt;/h2&gt;
&lt;h3&gt;Repository, working tree and bare repository&lt;/h3&gt;
&lt;p&gt;When you &lt;code&gt;init&lt;/code&gt; or &lt;code&gt;clone&lt;/code&gt; a git repository into a directory, you are, by default, left with 2 entities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;repository&lt;/strong&gt; who takes by default the form of a &lt;code&gt;.git&lt;/code&gt; directory. It
contains all the technical files and directories needed by git to maintain the
project&#39;s versions.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;working tree&lt;/strong&gt; which is all the files and directories that are under
version control.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A &lt;strong&gt;bare repository&lt;/strong&gt; is a repository without a working tree. It only contains
what you would normally find under the &lt;code&gt;.git&lt;/code&gt; directory.&lt;br /&gt;
It can be used as a remote! Indeed you can clone a repository from a local
directory if this last contains a bare instance of a git repository.&lt;/p&gt;
&lt;h3&gt;Stash&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;stash&lt;/code&gt; is a git command that allows you to record the current state of the
working tree and the index and then go back to a clean working tree. These
records are stored on a stack that can be visualized with &lt;code&gt;git stash list&lt;/code&gt;.&lt;br /&gt;
To recover the last record from the stack, run &lt;code&gt;git stash pop&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Setting the scene&lt;/h2&gt;
&lt;p&gt;If you had never heard about the command &lt;code&gt;git worktree&lt;/code&gt; before, there is a good
chance you think that you can only have one branch or commit checked out at a
time.&lt;/p&gt;
&lt;p&gt;This belief leads you to this inconvenient situation, when, for instance, you
need to abandon your work in progress in one branch,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;to support a colleague on another branch,&lt;/li&gt;
&lt;li&gt;address this review comment on your pending pull request,&lt;/li&gt;
&lt;li&gt;fix this bug spotted on QA stage that is a no go for going live,&lt;/li&gt;
&lt;li&gt;or worst in case of LIVE outage and that you need to deliver a hotfix as soon as possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the work is not in a state where you would commit it; quite often, if you are
aware of the &lt;code&gt;git stash&lt;/code&gt; command, you would:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;stage your work&lt;/li&gt;
&lt;li&gt;stash it&lt;/li&gt;
&lt;li&gt;check out the branch that need to be worked on&lt;/li&gt;
&lt;li&gt;do the work&lt;/li&gt;
&lt;li&gt;stage, commit, and push&lt;/li&gt;
&lt;li&gt;check out the branch you were formely on&lt;/li&gt;
&lt;li&gt;pop the last stashed piece of work&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And then only you can proceed with you work.&lt;br /&gt;
Phew, that is a lot of inconvenience.&lt;/p&gt;
&lt;h2&gt;git worktree to the rescue&lt;/h2&gt;
&lt;p&gt;With &lt;code&gt;git worktree&lt;/code&gt; you can link other working trees to your repository.&lt;/p&gt;
&lt;p&gt;Taken we are working on the &lt;code&gt;new-feature&lt;/code&gt; branch and that we need to abandon the
work to create a hotfix for the &lt;code&gt;main&lt;/code&gt; branch.&lt;br /&gt;
In the Terminal, and from the root of the directory that hosts the current
working tree, run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git worktree add ../hotfix main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This has created a new working tree, checked out to the &lt;code&gt;main&lt;/code&gt; branch, inside of
the directory &lt;code&gt;../hotfix&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now you can move to this directory to create the fix.&lt;br /&gt;
Stage, commit and push.&lt;/p&gt;
&lt;p&gt;If you come back to your previous directory, you should still have the
&lt;code&gt;new-feature&lt;/code&gt; branch checked out, and you should be able to  resume your work
where you left it at. Joy!&lt;/p&gt;
&lt;p&gt;At some point you also may want to get rid of the &lt;code&gt;hotfix&lt;/code&gt; worktree. Then run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git worktree remove hotfix
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If at anytime you want to show the existing worktree for a repository, run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git worktree list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Adding working trees in the parent or the current directory can quickly become a
mess.&lt;/p&gt;
&lt;h2&gt;A better working trees organization&lt;/h2&gt;
&lt;p&gt;I find that an organization like the one below is much more tidy!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my-awesome-project
 - git-technical-directory
 - new-feature
 - hotfix
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;bare repository&lt;/strong&gt; and &lt;strong&gt;.git&lt;/strong&gt; file to the rescue!&lt;/p&gt;
&lt;p&gt;Indeed we can proceed like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mkdir my-awesome-project
$ cd my-awesome-project

$ git clone --bare git@github.com:myname:my-awesome-project.git .bare

$ echo &amp;quot;gitdir: ./.bare&amp;quot; &amp;gt; .git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, we created a directory for our project, &lt;code&gt;cd&lt;/code&gt; into it, clone
&lt;code&gt;my-awesome-project&lt;/code&gt; as a bare repository into a &lt;code&gt;.bare&lt;/code&gt; directory. This &lt;code&gt;.bare&lt;/code&gt;
directory contains what the &lt;code&gt;.git&lt;/code&gt; directory contains if we would have gone for
a standard &lt;code&gt;git clone&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Where it is executed, the &lt;code&gt;git&lt;/code&gt; command either refer to a &lt;code&gt;.git&lt;/code&gt; directory or to
a &lt;code&gt;.git&lt;/code&gt; file. This last needs though to contain a pointer to the repository
directory. The pointer is the &lt;code&gt;gitdir&lt;/code&gt; setting.&lt;br /&gt;
Actually in every directory created by the &lt;code&gt;git worktree add&lt;/code&gt; command, you can
find a &lt;code&gt;.git&lt;/code&gt; file that contains this &lt;code&gt;gitdir&lt;/code&gt; setting.&lt;/p&gt;
&lt;p&gt;Now it is time to create the 2 worktrees:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git worktree add new-feature
$ git worktree add hotfix master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this stage our directory looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my-awesome-project
 - .bare
 - .git
 - new-feature
 - hotfix
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is pretty close from what we were aiming for and much better than this
mess:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hotfix
my-awesome-project
 - .git
 - .gitignore
 - assets
 - index.html
 - package.json
 ...
 - README.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope this &lt;code&gt;git worktree&lt;/code&gt; is as good breaking news for you as it was for me and
that it will improve you git experience.&lt;/p&gt;
&lt;h2&gt;Update January 14th, 2022&lt;/h2&gt;
&lt;p&gt;After using Git worktrees for a few weeks, in the manner described in this blog
post, I have noted two inefficiencies.&lt;/p&gt;
&lt;p&gt;The good news is that I came up with solutions to cover up for them. You will
find them as part of these complementary blog posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://morgan.cugerone.com/blog/workarounds-to-git-worktree-using-bare-repository-and-cannot-fetch-remote-branches/&quot;&gt;Workarounds to Git worktree using bare repository and cannot fetch remote branches&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;(Coming soon!) Git hook to have a npm based project to install dependencies at checkout&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-worktree&quot;&gt;Git worktree reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-stash&quot;&gt;Git stash reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=8aZW9mYOxhc&quot;&gt;What is a bare Git repo and why you need them on YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/67501784&quot;&gt;Answer talking about .git file and .git folder on Stackoverflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://infrequently.org/2021/07/worktrees-step-by-step/&quot;&gt;Git Worktrees Step-By-Step by Alex Russell&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Fri, 03 Sep 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-use-git-worktree-and-in-a-clean-way/</guid>
    </item>
    <item>
       <title>How to disable a variable font&#39;s variation features with open source tools</title>
       <link>https://morgan.cugerone.com/blog/how-to-disable-variable-fonts-variation-features-with-open-source-solution/</link>
       <description>&lt;p&gt;Today at work I was told to integrate a variable font on our pages. Once
integrated I found out that the font, despite converted to &lt;code&gt;.woff2&lt;/code&gt; format was
still weighting half a mega byte.&lt;br /&gt;
This font featured several variations, for instance the Width, Weight and Optical size variations.
In our use case we were just using the Weight variation.&lt;br /&gt;
I then asked myself, is there a way to strip features from a variable font?&lt;br /&gt;
Hence, not being a designer and not having fancy paid applications at my
disposal I was in reach for an open source solution.&lt;/p&gt;
&lt;p&gt;After quite some research I found the perfect set of tools!&lt;/p&gt;
&lt;p&gt;Below is my step-by-step guide to achieve striping out 2 variation features out
of a font, as well as reducing the Weight variation range.&lt;/p&gt;
&lt;h2&gt;What you need&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A variable font, let&#39;s call it &lt;code&gt;&amp;quot;MyAwesomeVariableFont&amp;quot;&lt;/code&gt;, that includes a bunch
of variation features and in its &lt;code&gt;.ttf&lt;/code&gt; (True Type Font) form&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fonttools&lt;/code&gt; command line tool (&lt;a href=&quot;https://pypi.org/project/fonttools/&quot;&gt;Install fonttools&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fonttools.readthedocs.io/en/latest/varLib/instancer.html&quot;&gt;varLib instancer documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;woff2_compress&lt;/code&gt; command line tool (Get up to speed by following &lt;a href=&quot;https://henry.codes/writing/how-to-convert-variable-ttf-font-files-to-woff2/&quot;&gt;How To Convert Variable TTF Font Files to WOFF2&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Generating MyAwesomeVariableFont.woff2 partial variable font&lt;/h2&gt;
&lt;p&gt;In the below commands, it is considered that the command line tools are in your
&lt;code&gt;$PATH&lt;/code&gt;, if not you can also use the absolute path to their binaries.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download MyAwesomeVariableFont font under the name of &lt;code&gt;MyAwesomeVariableFont.ttf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In the Terminal navigates to the folder you have just downloaded the font to&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;fonttools varLib.instancer ./MyAwesomeVariableFont.ttf wdth=drop opsz=drop wght=300:700&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;woff2_compress ./MyAwesomeVariableFont-partial.ttf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;mv ./MyAwesomeVariableFont-partial.woff2 ./MyAwesomeVariableFont.woff2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Copy &lt;code&gt;MyAwesomeVariableFont.woff2&lt;/code&gt; to your app&#39;s font folder&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the above steps, only &lt;code&gt;3.&lt;/code&gt; and &lt;code&gt;4.&lt;/code&gt; need deeper explanation.&lt;/p&gt;
&lt;p&gt;In step &lt;code&gt;3.&lt;/code&gt; we use the varLib instancer in order to drop the Width (wdth) and
the Optical size (opsz) variation features as well as to restrict the Weight
(wght) variations to a range that spans from a &lt;code&gt;font-weight&lt;/code&gt; of &lt;code&gt;300&lt;/code&gt; to &lt;code&gt;400&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In step &lt;code&gt;4.&lt;/code&gt; we run &lt;code&gt;woff2_compress&lt;/code&gt; CLI tool to compress our &lt;code&gt;.ttf&lt;/code&gt; generated
partial font to the &lt;code&gt;.woff2&lt;/code&gt; format, much more suited for the web.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Now, once loaded on your site/application, you should only be able to apply
variations on the Weight axis, and from &lt;code&gt;300&lt;/code&gt; to &lt;code&gt;700&lt;/code&gt;.&lt;br /&gt;
And most importantly you should have drastically reduce the footprint of your
variable font.&lt;br /&gt;
In my case the &lt;code&gt;.woff2&lt;/code&gt; file footprint had decreased by 73%.&lt;/p&gt;
&lt;p&gt;Feel free to explore the &lt;a href=&quot;https://fonttools.readthedocs.io/en/latest/varLib/instancer.html&quot;&gt;varLib instancer documentation&lt;/a&gt;
to address your needs.&lt;/p&gt;
</description>
       <pubDate>Fri, 27 Aug 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-disable-variable-fonts-variation-features-with-open-source-solution/</guid>
    </item>
    <item>
       <title>How do browsers process the @font-face src descriptor list</title>
       <link>https://morgan.cugerone.com/blog/how-do-browsers-process-the-font-face-src-descriptor-list/</link>
       <description>&lt;p&gt;You may have come across the &lt;code&gt;src&lt;/code&gt; descriptor of the &lt;code&gt;@font-face&lt;/code&gt; CSS rule and
wonder how is this actually processed by the browser.&lt;br /&gt;
Sure there is something about the font&#39;s extension and/or the &lt;code&gt;format&lt;/code&gt; hint, but
what if the browser does support many of the multiple font type listed?&lt;/p&gt;
&lt;p&gt;To answer this question I will just quote the W3C recommendations website:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Its value is a prioritized, comma-separated list of external references or
locally-installed font face names. When a font is needed the user agent
iterates over the set of references listed, using the first one it can
successfully activate. Fonts containing invalid data or local font faces that
are not found are ignored and the user agent loads the next font in the list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hence quote on &lt;code&gt;format&lt;/code&gt; hints:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The format hint contains a comma-separated list of format strings that denote
well-known font formats. Conformant user agents must skip downloading a font
resource if the format hints indicate only unsupported or unknown font
formats. If no format hints are supplied, the user agent should download the
font resource.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;/* Load WOFF2 font if possible, otherwise WOFF, else use OpenType font */
@font-face {
  font-family: bodytext;
  src: url(ideal-sans-serif.woff2) format(&amp;quot;woff2&amp;quot;),
       url(good-sans-serif.woff) format(&amp;quot;woff&amp;quot;),
       url(basic-sans-serif.ttf) format(&amp;quot;opentype&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-fonts-3/#descdef-src&quot;&gt;Font reference: the src descriptor, on www.w3.org&lt;/a&gt;.&lt;/p&gt;
</description>
       <pubDate>Thu, 26 Aug 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-do-browsers-process-the-font-face-src-descriptor-list/</guid>
    </item>
    <item>
       <title>How to locally delete all remotely merged git branches</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-locally-delete-all-remotely-merged-git-branches/</link>
       <description>&lt;p&gt;If you are like me and have a bad habit of not deleting your local branches as
you merge them and delete them remotely, this one is for you.&lt;/p&gt;
&lt;h2&gt;A two commands solution&lt;/h2&gt;
&lt;p&gt;First command to fetch but as well prune any branches that no longer exist on
the remote branch.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git fetch -p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;-p&lt;/code&gt; is short for &lt;code&gt;--prune&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that we have a clean slate we can perform an efficient deletion with the
second command:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git branch -vv | grep &#39;: gone]&#39;|  grep -v &amp;quot;&#92;*&amp;quot; | awk &#39;{ print $1; }&#39; | xargs git branch -D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is it decomposed:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git branch -vv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which lists your local branches and including &amp;quot;gone&amp;quot; if it is not present
anymore remotely.  &lt;code&gt;-vv&lt;/code&gt; means very verbose.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;grep &#39;: gone]&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which filters all lines including &lt;code&gt;: gone]&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;grep -v &amp;quot;&#92;*&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which ignores the currently checked out branch.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;awk &#39;{print $1}&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which grabs the first column in the output, being the branch name.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;xargs git branch -D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which runs &lt;code&gt;git branch -D&lt;/code&gt; for the names of the filtered branches.&lt;/p&gt;
&lt;p&gt;Et voilà!&lt;/p&gt;
&lt;p&gt;If for some reasons you want to exclude some branches that would show up in the
filtered list, amend the &lt;code&gt;grep -v &amp;quot;&#92;*&amp;quot;&lt;/code&gt; command to something like &lt;code&gt;egrep -v &amp;quot;(^&#92;*|branch-to-keep1|branch-to-keep2)&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/a/46192689/9461391&quot;&gt;Remove branches not on remote, on Stack
Overflow&lt;/a&gt;.&lt;/p&gt;
</description>
       <pubDate>Mon, 09 Aug 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-locally-delete-all-remotely-merged-git-branches/</guid>
    </item>
    <item>
       <title>Restore your easier window navigation mappings on Netrw buffers in Vim</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-enable-window-command-mappings-on-netrw-buffers/</link>
       <description>&lt;p&gt;If you are like me and have added the below mappings into your &lt;code&gt;.vimrc&lt;/code&gt; file as
mappings to window commands meant for navigation...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot; Easier window navigation.
map &amp;lt;C-h&amp;gt; &amp;lt;C-w&amp;gt;h
map &amp;lt;C-j&amp;gt; &amp;lt;C-w&amp;gt;j
map &amp;lt;C-k&amp;gt; &amp;lt;C-w&amp;gt;k
map &amp;lt;C-l&amp;gt; &amp;lt;C-w&amp;gt;l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... you may have figured out that they do not work on Netrw buffers.&lt;/p&gt;
&lt;p&gt;Below is the way to fix that...&lt;/p&gt;
&lt;p&gt;First off you need the following function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function NetrwMappings()
	nnoremap &amp;lt;buffer&amp;gt; &amp;lt;C-h&amp;gt; :wincmd h&amp;lt;cr&amp;gt;
	nnoremap &amp;lt;buffer&amp;gt; &amp;lt;C-j&amp;gt; :wincmd j&amp;lt;cr&amp;gt;
	nnoremap &amp;lt;buffer&amp;gt; &amp;lt;C-k&amp;gt; :wincmd k&amp;lt;cr&amp;gt;
	nnoremap &amp;lt;buffer&amp;gt; &amp;lt;C-l&amp;gt; :wincmd l&amp;lt;cr&amp;gt;
endfunction
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally the following auto commands group that lets you set these remaps
when on &lt;code&gt;netrw&lt;/code&gt; buffer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;augroup netrw_mappings
  autocmd!
  autocmd filetype netrw call NetrwMappings()
augroup END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add these two last code blocks to your &lt;code&gt;.vimrc&lt;/code&gt; then re-source it and or restart
your Vim and enjoy!&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/a/34139843/9461391&quot;&gt;Answer on a Stack Overflow&#39;s thread&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Mon, 12 Jul 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-enable-window-command-mappings-on-netrw-buffers/</guid>
    </item>
    <item>
       <title>Today I learned: How to encode/decode base64 string from the command line</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-encode-and-decode-base64-string-from-command-line/</link>
       <description>&lt;p&gt;Usually in order to encode/decode a piece of string I would hunt for an online
tool to do so. Today, I have seen a colleague in need to decode some base64
token, do it right from her command line.&lt;/p&gt;
&lt;p&gt;Here are the magic commands:&lt;/p&gt;
&lt;h2&gt;Encode a string to base64 from the command line&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;echo -n &#39;string-to-be-encoded&#39; | base64
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above command the &lt;code&gt;-n&lt;/code&gt; flag ensures you do not miss a hidden character
like line breaks...&lt;/p&gt;
&lt;p&gt;This command outputs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;c3RyaW5nLXRvLWJlLWVuY29kZWQ=
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Decode a base64 string from the command line&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;echo -n &#39;c3RyaW5nLXRvLWJlLWRlY29kZWQ=&#39; | base64 --decode
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command outputs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string-to-be-decoded%
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything in front of the last &lt;code&gt;%&lt;/code&gt; character is the original string.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;Find out how to do these operations using files rather than strings within the
article: &lt;a href=&quot;https://www.serverlab.ca/tutorials/linux/administration-linux/how-to-base64-encode-and-decode-from-command-line/&quot;&gt;How to base64 encode and decode from command-line&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Tue, 06 Jul 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-encode-and-decode-base64-string-from-command-line/</guid>
    </item>
    <item>
       <title>Today I learned: How to upload a buffer as a file to a Google Cloud Storage bucket</title>
       <link>https://morgan.cugerone.com/blog/how-to-upload-a-buffer-as-a-file-to-a-google-cloud-storage-bucket/</link>
       <description>&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;Today I needed to upload some file to a Google Cloud Storage bucket.&lt;br /&gt;
Many of examples out there are illustrated with scenarios using a file already
stored on the file system or coming from some &lt;code&gt;POST&lt;/code&gt; request.&lt;br /&gt;
None of these where matching my use case. I needed to upload a JSON file I would
build from a JSON object.&lt;br /&gt;
I had no intent to persist this file onto the server&#39;s file system, therefore
Node.JS &lt;code&gt;Buffer&lt;/code&gt; would be a great pick.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;First off, you need the &lt;a href=&quot;https://www.npmjs.com/package/@google-cloud/storage&quot;&gt;@google-cloud/storage npm
module&lt;/a&gt;, which is the
Node.js client for the upload Job. So go ahead and run &lt;code&gt;npm install @google-cloud/storage&lt;/code&gt; at the root of your project.&lt;/p&gt;
&lt;p&gt;As stated in Google APIs documentation, before you begin:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://console.cloud.google.com/project&quot;&gt;Select or create a Cloud Platform project.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://support.google.com/cloud/answer/6293499#enable-billing&quot;&gt;Enable billing for your project.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://console.cloud.google.com/flows/enableapi?apiid=storage-api.googleapis.com&quot;&gt;Enable the Google Cloud Storage API.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.google.com/docs/authentication/getting-started&quot;&gt;Set up authentication with a service account&lt;/a&gt; so you can access the API from your local workstation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;On top of this I would add &lt;a href=&quot;https://cloud.google.com/storage/docs/creating-buckets&quot;&gt;Create a bucket&lt;/a&gt; to be used as
the uploads destination storage.&lt;/p&gt;
&lt;p&gt;Now it&#39;s coding time...&lt;/p&gt;
&lt;p&gt;In the following example I turn a JSON object into a String before uploading,
but you could go straight with the String.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const {Storage} = require(&#39;@google-cloud/storage&#39;);
const character = {
	firstName: &#39;Harry&#39;,
	lastName: &#39;Potter&#39;
};

// Turns the object into a String and then a buffer.
const fileContent = JSON.stringify(character, null, 4);
const fileBuffer = Buffer.from(fileContent, &#39;utf-8&#39;);

// Creates a client.
const storage = new Storage({
	projectId: &#39;your-project-id&#39;,
	keyFilename: &#39;file-path-to-your-google-service-account-key&#39;
});

const bucket = storage.bucket(&#39;name-of-the-upload-bucket&#39;));
const file = bucket.file(&#39;name-of-the-destination-file&#39;);

// Uploads the file.
file.save(fileBuffer).then(() =&amp;gt; {
	// Success handling...
}).catch(error =&amp;gt; {
	// Error handling...
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In case you need to programmatically check if the file content stored is as you
expect it. In the &lt;code&gt;then&lt;/code&gt; block you can &amp;quot;download&amp;quot; the file to console log its
content as demonstrated below:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// Uploads the file.
file.save(fileBuffer).then(aync () =&amp;gt; {
	const checkedFile = bucket.file(&#39;name-of-the-destination-file&#39;);
	const content = await checkedFile.download();
	console.log(`File content: ${content}`);
}).catch(error =&amp;gt; {
	// Error handling...
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s all folks!&lt;/p&gt;
</description>
       <pubDate>Tue, 06 Jul 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-upload-a-buffer-as-a-file-to-a-google-cloud-storage-bucket/</guid>
    </item>
    <item>
       <title>Today I learned: How to &quot;include&quot; a link inside a form input label</title>
       <link>https://morgan.cugerone.com/blog/how-to-include-link-into-form-input-label/</link>
       <description>&lt;h2&gt;Anti-Pattern&lt;/h2&gt;
&lt;p&gt;You may be familiar with this: A checkbox associated with a label that contains
a link to a Terms and Conditions page. It is usually mapped as demonstrated in
below code snippet.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;label for=&amp;quot;tac&amp;quot;&amp;gt;
  &amp;lt;input id=&amp;quot;tac&amp;quot; type=&amp;quot;checkbox&amp;quot; name=&amp;quot;terms-and-conditions&amp;quot;&amp;gt;
  I agree to the &amp;lt;a href=&amp;quot;terms-and-conditions.html&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Terms and Conditions&amp;lt;/a&amp;gt;
&amp;lt;/label&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I would flag this practice as an Anti-Pattern, as it is too often used, but
endangers the accessibility of your form.&lt;br /&gt;
Indeed as the Mozilla Developer Network (MDN) mentions, it &amp;quot;makes it difficult
for people to activate the form input associated with the &lt;code&gt;label&lt;/code&gt;&amp;quot;.&lt;/p&gt;
&lt;p&gt;Basically, if the users click on the link part of the label, and this is likely
to happen as it is a common practice for checkboxes and radio buttons to click
the label to select the option; they will get to the target of that link but not
activate the form input. This can be, for some, a deceptive experience.&lt;/p&gt;
&lt;p&gt;The rule also applies, to not only anchors (commonly called links), but for any
other interactive elements such as &lt;code&gt;button&lt;/code&gt; elements.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;The solution consists in taking the anchor out of the label as demonstrated in
the below code snippet.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;label for=&amp;quot;tac&amp;quot;&amp;gt;
  &amp;lt;input id=&amp;quot;tac&amp;quot; type=&amp;quot;checkbox&amp;quot; name=&amp;quot;terms-and-conditions&amp;quot;&amp;gt;
  I agree to the Terms and Conditions
&amp;lt;/label&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;a href=&amp;quot;terms-and-conditions.html&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Read our Terms and Conditions&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label&quot;&gt;Mozilla Developer Network &lt;label&gt; element article&lt;/label&gt;&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Tue, 29 Jun 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-include-link-into-form-input-label/</guid>
    </item>
    <item>
       <title>Today I learned: How to match a portion of text that spans over multiple lines with a JavaScript regular expression</title>
       <link>https://morgan.cugerone.com/blog/how-to-match-a-portion-of-text-that-spans-over-mutli-lines-with-a-javascript-regex/</link>
       <description>&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;Let&#39;s say you have the following 5 lines long quote by Mark Twain:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Keep away from people who try to belittle your ambitions.
Small people always do that,
but the really great make you feel that you,
too,
can become great.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you wish to match, with a regular expression, from &lt;code&gt;people&lt;/code&gt; on &lt;code&gt;line 1&lt;/code&gt;,
and until &lt;code&gt;really&lt;/code&gt; on &lt;code&gt;line 3&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Hint: Spotlight on a very useful set of tokens&lt;/h2&gt;
&lt;p&gt;The token &lt;code&gt;[^]&lt;/code&gt; lets you match any character, including new line.&lt;br /&gt;
If you append the &lt;code&gt;*&lt;/code&gt; quantifier token to it, it matches what matches &lt;code&gt;[^]&lt;/code&gt;
but between &lt;code&gt;zero&lt;/code&gt; and an &lt;code&gt;unlimited&lt;/code&gt; amount of times.&lt;/p&gt;
&lt;p&gt;Beware though, because the token &lt;code&gt;[^]&lt;/code&gt; seems to only work in JavaScript.&lt;br /&gt;
An alternative to it seems to be &lt;code&gt;[&#92;s&#92;S]&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&#92;s&lt;/code&gt; matches any whitespace character&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&#92;S&lt;/code&gt; matches any non-whitespace character&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;h3&gt;Using &lt;code&gt;[^]*&lt;/code&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;/people[^]*.*really/m
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This, according to &lt;a href=&quot;https://regex101.com/&quot;&gt;regex101.com&lt;/a&gt; goes as follow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;people&lt;/code&gt; matches the characters &lt;code&gt;people&lt;/code&gt; literally (case sensitive)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[^]&lt;/code&gt; matches any character, including &lt;code&gt;newline&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; matches the previous token between zero and unlimited times, as many
times as possible, giving back as needed (greedy)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.&lt;/code&gt; matches any character (except for line terminators)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;really&lt;/code&gt; matches the characters &lt;code&gt;really&lt;/code&gt; literally (case sensitive)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Global pattern flag:&lt;br /&gt;
&lt;code&gt;m modifier&lt;/code&gt;: multi line. Causes ^ and $ to match the begin/end of each line
(not only begin/end of string)&lt;/p&gt;
&lt;h3&gt;Using &lt;code&gt;[&#92;s&#92;S]*&lt;/code&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;/people[&#92;s&#92;S]*.*really/m
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This, according to &lt;a href=&quot;https://regex101.com/&quot;&gt;regex101.com&lt;/a&gt; goes as follow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;people&lt;/code&gt; matches the characters &lt;code&gt;people&lt;/code&gt; literally (case sensitive)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&#92;s&lt;/code&gt; matches any whitespace character (equivalent to &lt;code&gt;[&#92;r&#92;n&#92;t&#92;f&#92;v &#92;u00a0&#92;u1680&#92;u2000-&#92;u200a&#92;u2028&#92;u2029&#92;u202f&#92;u205f&#92;u3000&#92;ufeff]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&#92;S&lt;/code&gt; matches any non-whitespace character (equivalent to &lt;code&gt;[^&#92;r&#92;n&#92;t&#92;f&#92;v &#92;u00a0&#92;u1680&#92;u2000-&#92;u200a&#92;u2028&#92;u2029&#92;u202f&#92;u205f&#92;u3000&#92;ufeff]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; matches the previous token between zero and unlimited times, as many
times as possible, giving back as needed (greedy)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.&lt;/code&gt; matches any character (except for line terminators)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;really&lt;/code&gt; matches the characters &lt;code&gt;really&lt;/code&gt; literally (case sensitive)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Global pattern flag:&lt;br /&gt;
&lt;code&gt;m modifier&lt;/code&gt;: multi line. Causes ^ and $ to match the begin/end of each line
(not only begin/end of string)&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/6712015/9461391&quot;&gt;Answer on Stack overflow &amp;quot;Regular Expressions- Match Anything&amp;quot; question&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://regex101.com/&quot;&gt;Regular expression 101 website&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Mon, 28 Jun 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-match-a-portion-of-text-that-spans-over-mutli-lines-with-a-javascript-regex/</guid>
    </item>
    <item>
       <title>Today I learned: How to suspend Vim temporarily, run some commands, and go back</title>
       <link>https://morgan.cugerone.com/blog/how-to-suspend-vim-temporarily-run-some-commands-and-go-back/</link>
       <description>&lt;h2&gt;Two magic commands&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;In Vim, &lt;code&gt;CTRL + z&lt;/code&gt; suspends it, putting its process in the background. You
land back, in your Terminal, where you launch the &lt;code&gt;vim&lt;/code&gt; process.&lt;/li&gt;
&lt;li&gt;In the terminal, &lt;code&gt;fg&lt;/code&gt; puts back the background process in the foreground.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;A use case out of so many&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;You are coding in Vim&lt;/li&gt;
&lt;li&gt;You want to quickly lint your all code base to capture lint issues&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CTRL + z&lt;/code&gt; to go back to the Terminal&lt;/li&gt;
&lt;li&gt;Run your lint command, in my case: &lt;code&gt;npm run lint&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;fg&lt;/code&gt; to jump back where you left your Vim&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Although I am using TMUX and could have a dedicated split or window for the lint
purpose I could switch to, I found that presented solution requires less brain
power.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/1879219/how-to-temporarily-exit-vim-and-go-back&quot;&gt;&amp;quot;How to temporarily exit Vim and go back&amp;quot; Stack overflow thread&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Sat, 19 Jun 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-suspend-vim-temporarily-run-some-commands-and-go-back/</guid>
    </item>
    <item>
       <title>Bash command chaining operators</title>
       <link>https://morgan.cugerone.com/blog/wiki-bash-command-chaining-operators/</link>
       <description>&lt;h2&gt;Semicolon operator (;)&lt;/h2&gt;
&lt;p&gt;The semicolon operator executes the commands sequentially.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ command1; command2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above instruction will first execute &lt;code&gt;command1&lt;/code&gt;. On both success or failure
of &lt;code&gt;command1&lt;/code&gt;, it will go ahead and execute &lt;code&gt;command2&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Ampersand operator (&amp;amp;)&lt;/h2&gt;
&lt;p&gt;The ampersand operator positionned after a command, executes it in the
background. When chaining commands, where each command is followed by the &lt;code&gt;&amp;amp;&lt;/code&gt;
operator, all commands will be executed in background, simultaneously.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ command1 &amp;amp; command2 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above instruction will execute &lt;code&gt;command1&lt;/code&gt; and &lt;code&gt;command2&lt;/code&gt; in background,
simultaneously.&lt;/p&gt;
&lt;h2&gt;AND operator (&amp;amp;&amp;amp;)&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;AND&lt;/code&gt;(double ampersand) operator executes the command after the operator
only if the one before succeeds.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ command1 &amp;amp;&amp;amp; command2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above instruction will execute &lt;code&gt;command2&lt;/code&gt; only if &lt;code&gt;command1&lt;/code&gt; succeeds.&lt;/p&gt;
&lt;h2&gt;OR operator (||)&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;OR&lt;/code&gt;(double pipe) operator acts as a &lt;code&gt;else&lt;/code&gt; statement. It executes the command after the operator only if the one before fails.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ command1 || command2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above instruction will execute &lt;code&gt;command2&lt;/code&gt; only if &lt;code&gt;command1&lt;/code&gt; fails.&lt;/p&gt;
&lt;h2&gt;PIPE operator (|)&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;PIPE&lt;/code&gt; operator lets the previous command standard output to be passed as the standard input of the following command. This often comes in handy when you want to filter the output of the previous command.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ history | grep npm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above instruction will execute the &lt;code&gt;history&lt;/code&gt; command, and filter its output to only display lines including the string &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;AND – OR operator (&amp;amp;&amp;amp; – ||)&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;AND – OR&lt;/code&gt; operator is nothing else than the combination of &lt;code&gt;AND&lt;/code&gt; and &lt;code&gt;OR&lt;/code&gt;
operators. It acts as a &lt;code&gt;if – else&lt;/code&gt; statement.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ command1 &amp;amp;&amp;amp; upon-command1-success || upon-command1-failure
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above instruction will execute &lt;code&gt;command1&lt;/code&gt; first. If it succeed, it will
execute &lt;code&gt;upon-command1-success&lt;/code&gt;. If &lt;code&gt;command1&lt;/code&gt; fails, it will execute
&lt;code&gt;upon-command1-failure&lt;/code&gt;&lt;/p&gt;
</description>
       <pubDate>Wed, 19 May 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/wiki-bash-command-chaining-operators/</guid>
    </item>
    <item>
       <title>Today I learned: How to log a JavaScript object with indentation to the console</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-how-to-log-javascript-object-with-indentation-to-the-console/</link>
       <description>&lt;h2&gt;Use JSON.stringify() function&lt;/h2&gt;
&lt;p&gt;Although I was using the &lt;code&gt;JSON.stringify()&lt;/code&gt; function for years; I found myself
logging JavaScript objects to the console the most unproductive way.&lt;br /&gt;
Worse, upon need, I would copy paste the output into a JSON formatter.&lt;/p&gt;
&lt;h2&gt;Efficiently use JSON.stringify() function&lt;/h2&gt;
&lt;p&gt;I discovered today that the &lt;code&gt;JSON.stringify()&lt;/code&gt; function takes two additional
arguments: &lt;code&gt;replacer&lt;/code&gt; and &lt;code&gt;space&lt;/code&gt;.&lt;br /&gt;
I will leave out the &lt;code&gt;replacer&lt;/code&gt; argument of this post, but the &lt;code&gt;space&lt;/code&gt; argument
is all I ever needed.&lt;/p&gt;
&lt;p&gt;As stated in MDN:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;space&lt;/code&gt; argument may be used to control spacing in the final string.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If it is a number&lt;/strong&gt;, successive levels in the stringification will each be
indented by this many space characters (up to 10).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If it is a string&lt;/strong&gt;, successive levels will be indented by this string (or
the first ten characters of it).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This means that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;JSON.stringify({ a: 2 }, null, &#39; &#39;);&lt;/code&gt; will indent by 1 space&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JSON.stringify({ a: 2 }, null, 1);&lt;/code&gt; will also indent by 1 space&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JSON.stringify({ a: 2 }, null, 4);&lt;/code&gt; will also indent by 4 spaces&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JSON.stringify({ a: 2 }, null, 15);&lt;/code&gt; will indent by 10 spaces&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JSON.stringify({ a: 2 }, null, &lt;/code&gt;&#92;t&lt;code&gt;);&lt;/code&gt; will indent with tabs&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Example: Output indented with tabs&lt;/h2&gt;
&lt;p&gt;Below your can find the example taken from MDN for indenting with tabs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JSON.stringify({ uno: 1, dos: 2 }, null, &#39;&#92;t&#39;);
// returns the string:
// &#39;{
//     &amp;quot;uno&amp;quot;: 1,
//     &amp;quot;dos&amp;quot;: 2
// }&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_space_argument&quot;&gt;MDN article about JSON.stringify, space argument section&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Wed, 17 Mar 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-how-to-log-javascript-object-with-indentation-to-the-console/</guid>
    </item>
    <item>
       <title>Today I learned: How to delete until the beginning of the line including the cursor in Vim</title>
       <link>https://morgan.cugerone.com/blog/how-to-delete-until-the-beginning-of-the-line-including-the-cursor-in-vim/</link>
       <description>&lt;p&gt;Five years I have been using Vim, as well as consumming various content about it
such as blogs, books, screencasts, forums... Five years and I never came across
this single character that may make a difference.&lt;/p&gt;
&lt;h2&gt;Inconvenience&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: In the below text snippets, the square brackets symbolise the cursor, and the
character inside these brackets, the character being under the cursor.&lt;/p&gt;
&lt;p&gt;Let&#39;s say you have the following text snippet, and that you are in normal mode:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Today is[:]Tuesday
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you want to delete backward until the beginning of the line.&lt;/p&gt;
&lt;p&gt;First things that come in mind are usually the commands &lt;code&gt;d^&lt;/code&gt;, &lt;code&gt;d|&lt;/code&gt; or &lt;code&gt;d0&lt;/code&gt;.&lt;br /&gt;
But unfortunately, here is what you are left out with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[:]Tuesday
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see the character previously under the cursor is still present. This
does not meet the original expectation.&lt;/p&gt;
&lt;h2&gt;The reason&lt;/h2&gt;
&lt;p&gt;The reason behind this, is that the motions used above, &lt;code&gt;^&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt; are
defined as &lt;code&gt;exclusive&lt;/code&gt; in Vim.&lt;/p&gt;
&lt;p&gt;According to Vim documentation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A character motion is either &lt;code&gt;inclusive&lt;/code&gt; or &lt;code&gt;exclusive&lt;/code&gt;. When &lt;code&gt;inclusive&lt;/code&gt;, the
start and end position of the motion are included in the operation. When
&lt;code&gt;exclusive&lt;/code&gt;, the last character towards the end of the buffer is not included.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In our example the &amp;quot;last character towards the end of the buffer&amp;quot; is the &lt;code&gt;:&lt;/code&gt;,
therefore it is not deleted.&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;Hopefully, Vim has a mean to turn an &lt;code&gt;exclusive&lt;/code&gt; motion into an &lt;code&gt;inclusive&lt;/code&gt;
motion (and vice-versa), using the &lt;code&gt;v&lt;/code&gt; modifier.&lt;br /&gt;
Here are the &lt;code&gt;inclusive&lt;/code&gt; equivalent of the above presented commands:&lt;br /&gt;
&lt;code&gt;dv^&lt;/code&gt;, &lt;code&gt;dv|&lt;/code&gt; and &lt;code&gt;dv0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now applying one of these commands to the first text snippets produces the
following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tuesday
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bingo!&lt;/p&gt;
&lt;h2&gt;Beyond deletion&lt;/h2&gt;
&lt;p&gt;Since the behaviour comes from the nature of the motion rather than the
operator, this can be applied to other operations too, such as &lt;code&gt;change&lt;/code&gt; (&lt;code&gt;c&lt;/code&gt;) or
&lt;code&gt;yank&lt;/code&gt; (&lt;code&gt;y&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Below, is the use case of willing to change &lt;code&gt;Today is: Tuesday&lt;/code&gt; to &lt;code&gt;Yesterday was Tuesday&lt;/code&gt;, starting with the text snippet and the cursor positioned on the &lt;code&gt;:&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Today is[:]Tuesday
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, type the sequence: &lt;code&gt;cv0Yesterday was &lt;/code&gt; and then &lt;code&gt;Escape&lt;/code&gt;. Now you should end up with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Yesterday was Tuesday
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;How to tell a motion is exclusive or inclusive?&lt;/h2&gt;
&lt;p&gt;In the Vim documentation, for each motion description, it provides its nature.&lt;br /&gt;
For instance here is the excerpt for the &lt;code&gt;0&lt;/code&gt; motion:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://vimhelp.org/motion.txt.html#0&quot; title=&quot;Motion 0 in Vim documentation&quot;&gt;0&lt;/a&gt;   To the first character of the line. &lt;a href=&quot;https://vimhelp.org/motion.txt.html#exclusive&quot; title=&quot;Exclusive in Vim documentation&quot;&gt;exclusive&lt;/a&gt; motion.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vimhelp.org/motion.txt.html#left-right-motions&quot;&gt;Left-right motions in Vim documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vimhelp.org/motion.txt.html#exclusive&quot;&gt;exclusive in Vim documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://superuser.com/a/1141049&quot;&gt;Vim delete motions include under the cursor on SuperUser&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Tue, 16 Feb 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-delete-until-the-beginning-of-the-line-including-the-cursor-in-vim/</guid>
    </item>
    <item>
       <title>Today I learned: How to show current buffer&#39;s path in Vim&#39;s normal mode</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-show-current-buffer-path-in-vim-from-normal-mode/</link>
       <description>&lt;p&gt;In case you are like me and opted for just having the filename showing in
status line, this might have its limitations.&lt;br /&gt;
Indeed, if you have two buffers sharing the same filename (e.g. &lt;code&gt;links.scss&lt;/code&gt;),
but displaying files stored at different locations, you may want to know which
one is which one (e.g. &lt;code&gt;settings/links.css&lt;/code&gt; or &lt;code&gt;mixins/links.scss&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;In normal mode, just type the shortcut &lt;code&gt;Ctrl-g&lt;/code&gt; and the file&#39;s path will be
printed in the command line area.&lt;/p&gt;
&lt;p&gt;An alternative, is to use the &lt;code&gt;:f&lt;/code&gt; command which is short for &lt;code&gt;:file&lt;/code&gt; and
achieve the same goal.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://vimhelp.org/editing.txt.html#CTRL-G&quot;&gt;Vim documentation&lt;/a&gt;&lt;/p&gt;
</description>
       <pubDate>Thu, 04 Feb 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-show-current-buffer-path-in-vim-from-normal-mode/</guid>
    </item>
    <item>
       <title>Today I learned: How to style a &lt;fieldset&gt;&#39;s &lt;legend&gt; element as display inline</title>
       <link>https://morgan.cugerone.com/blog/how-to-make-a-fieldset-legend-inline/</link>
       <description>&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;I was creating a sorting toolbar component made of a &lt;code&gt;fieldset&lt;/code&gt;, its &lt;code&gt;legend&lt;/code&gt;,
two &lt;code&gt;input&lt;/code&gt; of type &lt;code&gt;radio&lt;/code&gt;, their associated &lt;code&gt;label&lt;/code&gt; and finally a submit
&lt;code&gt;button&lt;/code&gt;. That&#39;s it for the semantic.&lt;/p&gt;
&lt;p&gt;In terms of presentation, the requirement was to hide the &lt;code&gt;input&lt;/code&gt;s only visually
so that they remain accessible, have the &lt;code&gt;legend&lt;/code&gt; and the &lt;code&gt;labels&lt;/code&gt; on the same
line.&lt;/p&gt;
&lt;p&gt;First thought was to use &lt;code&gt;flexbox&lt;/code&gt; and have the fieldset to be &lt;code&gt;display: flex&lt;/code&gt;
but that was where the problems started. The &lt;code&gt;legend&lt;/code&gt; would not flex. Then I
tried to make the &lt;code&gt;legend&lt;/code&gt; and &lt;code&gt;label&lt;/code&gt; &lt;code&gt;display: inline-block&lt;/code&gt;. Still no luck.&lt;br /&gt;
This was about where I started googling.&lt;/p&gt;
&lt;p&gt;I came across a bunch of statements:&lt;/p&gt;
&lt;p&gt;From &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Learn/Forms/Styling_web_forms&quot;&gt;MDN Styling web forms section&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;legend&amp;gt;&lt;/code&gt; element is okay to style, but it can be a bit tricky to control
placement of it. By default it is always positioned over the top border of its
&lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt; parent, near the top left corner. To position it somewhere else,
for example inside the fieldset somewhere, or near the bottom left corner, you
need to rely on positioning.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From &lt;a href=&quot;https://stackoverflow.com/questions/5818960/why-wont-my-legend-element-display-inline&quot;&gt;Stackoverflow thread: Why won&#39;t my legend element display inline?&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Legends are special. In particular, their default rendering can&#39;t be described
in CSS, so browsers use non-CSS means of rendering them. What that means is
that a statically positioned legend will be treated like a legend and be
separate from the actual content of the fieldset.&lt;br /&gt;
The weird doesn&#39;t end there; if you reverse the order of the span and the
legend, the legend will still show up on top in most browsers (but not in
Opera, apparently).&lt;br /&gt;
— &lt;cite&gt;&lt;a href=&quot;https://stackoverflow.com/users/720912/boris-zbarsky&quot;&gt;Boris Zbarsky&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Legends just don&#39;t accept &lt;code&gt;display: inline&lt;/code&gt; or &lt;code&gt;display: inline-block&lt;/code&gt;, but
you can give it &lt;code&gt;float: left&lt;/code&gt; and it will display similarly to what you want.&lt;br /&gt;
— &lt;cite&gt;&lt;a href=&quot;https://stackoverflow.com/users/143739/kzh&quot;&gt;kzh&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That was a mind blow right there!&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;The solution was to &lt;code&gt;float: left&lt;/code&gt; the &lt;code&gt;legend&lt;/code&gt; and the two &lt;code&gt;label&lt;/code&gt; as suggested
by &lt;a href=&quot;https://stackoverflow.com/users/143739/kzh&quot;&gt;kzh&lt;/a&gt; in the citation above. This
worked for me cross browser. I would not have expected &lt;code&gt;float: left&lt;/code&gt; to be my
saviour in 2021!&lt;/p&gt;
</description>
       <pubDate>Tue, 19 Jan 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-make-a-fieldset-legend-inline/</guid>
    </item>
    <item>
       <title>Vim CursorHold autocommand error when opening command line window</title>
       <link>https://morgan.cugerone.com/blog/troubleshooting-vim-error-while-processing-cursorHold-autocommands-in-command-line-window/</link>
       <description>&lt;h2&gt;Trouble&lt;/h2&gt;
&lt;p&gt;When opening the Command-line window in Vim (&lt;code&gt;q:&lt;/code&gt; in Normal Mode) I was getting
the following error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Error detected while processing CursorHold Autocommands for &amp;quot;*&amp;quot;:
E11: Invalid in command-line window; &amp;lt;CR&amp;gt; executes, CTRL-C quits: checktime
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;This is most likely to happen if you have in your &lt;code&gt;.vimrc&lt;/code&gt;, or if one of your
plugin is running, such an autocommand: &lt;code&gt;autocmd CursorHold * checktime&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;Googling for a bit I came across this closed &lt;a href=&quot;https://github.com/sheerun/vim-polyglot/issues/604&quot;&gt;issue of vim-polyglot Github
repository&lt;/a&gt; that provides
the solution.&lt;/p&gt;
&lt;p&gt;Just add &lt;code&gt;silent!&lt;/code&gt; between &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;checktime&lt;/code&gt; and that&#39;s all, the warning
should just silent out.&lt;br /&gt;
You may have to not only reload your &lt;code&gt;.vimrc&lt;/code&gt;, but to also quit and re-open Vim
for this change to take effect.&lt;/p&gt;
&lt;p&gt;Once again here is the fix:&lt;/p&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;autocmd CursorHold * checktime
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;autocmd CursorHold * silent! checktime
&lt;/code&gt;&lt;/pre&gt;
</description>
       <pubDate>Mon, 18 Jan 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/troubleshooting-vim-error-while-processing-cursorHold-autocommands-in-command-line-window/</guid>
    </item>
    <item>
       <title>Express.js error: Cannot set headers after they are sent to the client</title>
       <link>https://morgan.cugerone.com/blog/troubleshooting-express-error-cannot-set-headers-after-they-are-sent-to-the-client/</link>
       <description>&lt;h2&gt;Trouble&lt;/h2&gt;
&lt;p&gt;Your Express.js server is throwing an &lt;code&gt;ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client&lt;/code&gt; and you have a useless stack trace to work
from like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:467:11)
    at ServerResponse.header (/usr/src/app/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/usr/src/app/node_modules/express/lib/response.js:170:12)
    at done (/usr/src/app/node_modules/express/lib/response.js:1008:10)
    at render_file (/usr/src/app/node_modules/hbs/lib/hbs.js:49:14)
    at ReadFileContext.callback (/usr/src/app/node_modules/hbs/lib/hbs.js:168:16)
    at FSReqCallback.readFileAfterOpen [as oncomplete] (fs.js:232:13)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Why the heck do I get this?&lt;/h2&gt;
&lt;p&gt;As the cause of this issue is extremely well explained in &lt;a href=&quot;https://www.codementor.io/@oparaprosper79/understanding-node-error-err_http_headers_sent-117mpk82z8&quot;&gt;&amp;quot;Understanding Node
Error ERR_HTTP_HEADERS_SENT&amp;quot; by Prosper
Opara&lt;/a&gt;
I let you get the insights there.&lt;br /&gt;
I would just add to the article that the lack of using the &lt;code&gt;return&lt;/code&gt; keyword when
calling the Express &lt;code&gt;next()&lt;/code&gt; function may also cause the &lt;code&gt;ERR_HTTP_HEADERS_SENT&lt;/code&gt;
issue.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;By browsing the &lt;a href=&quot;https://github.com/expressjs/express&quot;&gt;Express.js git
repository&lt;/a&gt; I came across this &lt;a href=&quot;https://github.com/expressjs/express/issues/4060&quot;&gt;issue that
provides a very neat code
snippet&lt;/a&gt; that improves the
stack trace to identify the line responsible for the issue.&lt;/p&gt;
&lt;p&gt;The code snippet consists of a middleware that monkey patches the &lt;code&gt;res.render&lt;/code&gt;
and &lt;code&gt;res.send&lt;/code&gt; Express.js functions in order to prevent the application from
crashing and improve the logged stack trace.&lt;/p&gt;
&lt;p&gt;Here is the snippet:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.use((req, res, next) =&amp;gt; {
    const render = res.render;
    const send = res.send;
    res.render = function renderWrapper(...args) {
        Error.captureStackTrace(this);
        return render.apply(this, args);
    };
    res.send = function sendWrapper(...args) {
        try {
            send.apply(this, args);
        } catch (err) {
            console.error(`Error in res.send | ${err.code} | ${err.message} | ${res.stack}`);
        }
    };
    next();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you plug this onto your Express.js application you will get a much more
useful stack trace like below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Error in res.send | ERR_HTTP_HEADERS_SENT | Cannot set headers after they are sent to the client | Error
     at ServerResponse.renderWrapper [as render] (/usr/src/app/app/server.js:289:15)
     at index (/usr/src/app/app/controllers/home-controller.js:88:21)
     at processTicksAndRejections (internal/process/task_queues.js:89:5)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above stack trace the line responsible for the second &lt;code&gt;render&lt;/code&gt; is the
line &lt;code&gt;88&lt;/code&gt; of the &lt;code&gt;home-controller.js&lt;/code&gt; file. Bingo!&lt;/p&gt;
&lt;p&gt;All the credit should go to &lt;a href=&quot;https://github.com/jstarmx&quot;&gt;James Starkie a.k.a jstarmx on
Github&lt;/a&gt;. James you made my day on this one ☀️.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Do not forget to remote the middleware once you are done debugging 😉&lt;/p&gt;
</description>
       <pubDate>Thu, 14 Jan 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/troubleshooting-express-error-cannot-set-headers-after-they-are-sent-to-the-client/</guid>
    </item>
    <item>
       <title>No match error when testing an Express.js controller doing multiple calls to a same backend</title>
       <link>https://morgan.cugerone.com/blog/troubleshooting-no-match-error-when-testing-express-js-controller-doing-multiple-calls-to-same-backend/</link>
       <description>&lt;h2&gt;Trouble&lt;/h2&gt;
&lt;p&gt;Getting &lt;code&gt;Nock: No match for request ...&lt;/code&gt; with error code &lt;code&gt;ERR_NOCK_NO_MATCH&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;I had a controller requesting the same backend service but onto 2 different
endpoints. My intent was to mock these calls using the great &amp;quot;HTTP server
mocking and expectations library for Node.js&amp;quot;
&lt;a href=&quot;https://github.com/nock/nock&quot;&gt;Nock&lt;/a&gt;. This intent take the form of the below
code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const scope = nock(&#39;http://backend&#39;)
	.get(&#39;/user/details&#39;)
	.reply(200, {
		userId: 123,
		email: &#39;123@example.com&#39;
	})
	.post(&#39;/api&#39;)
	.reply(200, {
		data: {
			// data to be returned
		}
	});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When my controller was reaching the &lt;code&gt;/user/details&lt;/code&gt; endpoint it was being
matched and resolved, but when it was reaching the &lt;code&gt;/api&lt;/code&gt; on it was getting
&lt;code&gt;Nock: No match for request /api&lt;/code&gt; exception.&lt;/p&gt;
&lt;p&gt;I knew that interceptors, as stated in the Nock documentation, are removed as
they are used. Though, in my opinion I did not considered the &lt;code&gt;/api&lt;/code&gt; as yet used
because of the misleading message telling me it could not be matched.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;The solution was to append the call to the &lt;code&gt;.persist()&lt;/code&gt; method between
&lt;code&gt;nock(&#39;http://backend&#39;)&lt;/code&gt; and &lt;code&gt;get(&#39;/user/details&#39;)&lt;/code&gt; as shown in code below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const scope = nock(&#39;http://backend&#39;)
	.persist()
	.get(&#39;/user/details&#39;)
	.reply(200, {
		userId: 123,
		email: &#39;123@example.com&#39;
	})
	.post(&#39;/api&#39;)
	.reply(200, {
		data: {
			// data to be returned
		}
	});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I would have found the &lt;code&gt;.persist()&lt;/code&gt; call to be more intuitive if scoped at
endpoint level rather than at hostname level though. Well at least now my test
passes 🎉.&lt;/p&gt;
</description>
       <pubDate>Wed, 13 Jan 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/troubleshooting-no-match-error-when-testing-express-js-controller-doing-multiple-calls-to-same-backend/</guid>
    </item>
    <item>
       <title>How to repurpose a 2006 Macbook into a Linux laptop</title>
       <link>https://morgan.cugerone.com/blog/repurpose-a-2006-macbook-into-a-linux-laptop-running-lubuntu-16-04/</link>
       <description>&lt;h2&gt;Mission&lt;/h2&gt;
&lt;p&gt;Allocate an old computer to my daughter, as part of home schooling due to
COVID-19, so that she can attend Webex conference with her teacher and
classmates as well as sign into some online E-learning app.&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;For actually a few weeks I developed interest in the opportunity to convert an
aging iMac (mid-2011) into a Linux computer.&lt;br /&gt;
I have been hesitant by fear to mess it up or to embark onto a time consuming
project.&lt;br /&gt;
That was before I remembered I had an even older Mac around I could probably
mess up with and that could be useful for my daughter&#39;s Home schooling.&lt;/p&gt;
&lt;p&gt;This older Mac is an Apple Macbook from 2006 with 2GB of RAM.&lt;/p&gt;
&lt;p&gt;It was getting covered with dust in the bottom of a drawer for a few years
already.&lt;br /&gt;
Well, it looks like the current pandemic situation is giving it a chance the
revive, but under a new skin!&lt;/p&gt;
&lt;h2&gt;Getting ready&lt;/h2&gt;
&lt;p&gt;For starter, you need an ISO image of a suitable Linux distribution that this
computer could support.&lt;/p&gt;
&lt;p&gt;My initial choice was Ubuntu 16.04 (32bit), but ended up using a lighter one in
the name of Lubuntu 16.04 (32bit).&lt;/p&gt;
&lt;p&gt;This Macbook does not support booting from USB, so make sure the Mac you wish to
repurpose supports this before going wild about using Etcher to create a USB
flash drive to boot from. If your Mac support it, good for you and go ahead with
it.&lt;br /&gt;
In my case I burned the ISO on a DVD, from another Mac with optical drive.&lt;/p&gt;
&lt;p&gt;Here are the steps to get the install going:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href=&quot;http://cdimages.ubuntu.com/lubuntu/releases/16.04.6/release/&quot;&gt;Lubuntu 16.04 release download
page&lt;/a&gt; and grab
the image that fits your Mac. For my 2006 Macbook, it was &amp;quot;32-bit PC (i386)
desktop image&amp;quot;.&lt;/li&gt;
&lt;li&gt;Once downloaded, right click on the downloaded file in the Finder, and pick
the option to Burn it. Advice: You may want to select a low Burning speed to
avoid to waste a DVD-R with an aborted copy.&lt;/li&gt;
&lt;li&gt;On the target Mac, that hopefully has a working optical drive, insert the
DVD and restart it holding the &lt;code&gt;C&lt;/code&gt; key until it boots on the DVD.&lt;/li&gt;
&lt;li&gt;Follow the installation instructions with the choices that makes sense to
you.&lt;/li&gt;
&lt;li&gt;If you ever get to configure your Keyboard, do not just pick the language but
also the layout of the language, for instance, &amp;quot;English (Macintosh)&amp;quot;, because
English PC and Macintosh have different keyboard layouts 😉.&lt;/li&gt;
&lt;li&gt;At the end of the installation, you are asked to restart the computer.&lt;/li&gt;
&lt;li&gt;After restart, Boom! You should be running Lubuntu by now, congrats.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Software updates&lt;/h2&gt;
&lt;p&gt;You should be doing the Software updates in order to have, for instance, the
latest Firefox...&lt;/p&gt;
&lt;h2&gt;Configuring the Apple iSight webcam&lt;/h2&gt;
&lt;p&gt;Out of the box you won&#39;t be able to use your Mac internal webcam. It is though a
fairly simple task to achieve to configure it.&lt;/p&gt;
&lt;p&gt;Just use the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Get the AppleUSBVideoSupport file. You can find that file on an existing Mac
OSX 10.4 or 10.5 installation at this location:
&lt;code&gt;/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBVideoSupport.kext/Contents/MacOS/AppleUSBVideoSupport&lt;/code&gt; or you can download it from &lt;a href=&quot;http://dalmano.bplaced.net/turanct.zym.backup/AUVideoS.zip&quot;&gt;Download the zip that contains the AppleUSBVideoSupport file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Store the AppleUSBVideoSupport somewhere in your newly Lubuntu Mac.&lt;/li&gt;
&lt;li&gt;Open the Terminal(&lt;code&gt;Menu &amp;gt; System Tools &amp;gt; LXTerminal&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Update your repositories with &lt;code&gt;sudo apt-get update&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Install the iSight Firmware Tools with &lt;code&gt;sudo apt-get install isight-firmware-tools&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The installer will ask you for the AppleUSBVideoSupport file. give it the right path to that file.&lt;/li&gt;
&lt;li&gt;Reboot or log out and log back in. You can now use your iSight.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Where to go from here&lt;/h2&gt;
&lt;p&gt;You may want to optimize and customize your Lubuntu, right?&lt;br /&gt;
This &lt;a href=&quot;https://www.youtube.com/watch?v=X-ppIMezIgM&quot;&gt;Lubuntu 16.04 review and how to make it better video&lt;/a&gt;
does a great job at guiding you.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The repurposed Mac runs fairly smooth, at least much better than it was before
under OSX.&lt;br /&gt;
It is perfect for browsing the web unless you get to use some fancy online apps,
like Cisco Webex for instance.&lt;br /&gt;
Using this last one is possible through Firefox or Chrome add-on/extension. You
should give it a try to judge. In my case and at this stage I&#39;m not sure that my
issue with it was only related to CPU/RAM. This could also be a bandwidth issue.&lt;/p&gt;
&lt;p&gt;In the end, since my daughter&#39;s need is heavily relying on the ability to have
stable conference calls, it is less likely she will use that computer. On the
other hand, the E-learning online app was running smoothly though.&lt;/p&gt;
&lt;p&gt;The exercise was worth it in my opinion, because now I feel more confident to go
ahead and repurpose my mid-2011 iMac with most likely 64-bit Ubuntu.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ZJCv-2mIPsc&amp;amp;t=244s&quot;&gt;Tutorial: Installing Linux on an old
Macbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://turanct.wordpress.com/2010/06/11/use-your-macs-isight-on-ubuntu/&quot;&gt;Use your Mac’s iSight on
Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Sat, 09 Jan 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/repurpose-a-2006-macbook-into-a-linux-laptop-running-lubuntu-16-04/</guid>
    </item>
    <item>
       <title>Invalid file mode error when deploying a Node.js application to Cloud Foundry</title>
       <link>https://morgan.cugerone.com/blog/troubleshooting-invalid-file-mode-error-when-deploying-node-app-to-cloud-foundry/</link>
       <description>&lt;h2&gt;Trouble&lt;/h2&gt;
&lt;p&gt;Getting &lt;code&gt;Failed: The resource file mode is invalid: File mode &#39;444&#39; with path... is invalid. Minimum file mode is &#39;0600&#39;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;In my case it concerned a file nested in &lt;code&gt;node_modules/.cache&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;The solution was to add a &lt;code&gt;.cfignore&lt;/code&gt; file at the root of the application to
deploy.&lt;/p&gt;
&lt;p&gt;Here is the content of my &lt;code&gt;.cfignore&lt;/code&gt; file that solved the issue:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;node_modules/.cache
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Reference: &lt;a href=&quot;https://medium.com/cloud-foundry-foundation/deploy-a-nodejs-app-to-cloud-foundry-via-pivotal-bf2662f59a6f&quot;&gt;Deploy a Nodejs App to Cloud Foundry&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</description>
       <pubDate>Thu, 07 Jan 2021 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/troubleshooting-invalid-file-mode-error-when-deploying-node-app-to-cloud-foundry/</guid>
    </item>
    <item>
       <title>Create a pull/merge request starting from your terminal</title>
       <link>https://morgan.cugerone.com/blog/quick-tip-create-a-github-pull-request-starting-from-your-terminal/</link>
       <description>&lt;p&gt;Did you know, or even noticed?&lt;/p&gt;
&lt;p&gt;On your first &lt;code&gt;git push -u&lt;/code&gt; command you issue from your terminal, the &lt;code&gt;git&lt;/code&gt; CLI
offers you a link to straighly jump to creating the Pull/Merge request for your
current branch on repository host platform (e.g. Github, Gitlab...)?&lt;/p&gt;
&lt;p&gt;Try out...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout -b pr-test
echo &amp;quot;# Testing PR&amp;quot; &amp;gt; test.md
git add test.md
git commit -m &#39;Add test file&#39;
git push -u origin pr-test
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should be getting something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
...
remote: To create a merge request for pr-test, visit:
remote:   https://gitlab.com/morgaan/morgan.cugerone.com/-/merge_requests/new?merge_request%5Bsource_branch%5D=pr-test
remote:
...
 * [new branch]      pr-test -&amp;gt; pr-test
Branch &#39;pr-test&#39; set up to track remote branch &#39;pr-test&#39; from &#39;origin&#39;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now if you click the link in the console output (e.g. Cmd+click in iTerm2), you
should be brought to the page to create the Pull/Merge request for that branch.&lt;/p&gt;
</description>
       <pubDate>Fri, 16 Oct 2020 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/quick-tip-create-a-github-pull-request-starting-from-your-terminal/</guid>
    </item>
    <item>
       <title>Vim indentation options</title>
       <link>https://morgan.cugerone.com/blog/vim-indentation-options/</link>
       <description>&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tabstop&lt;/code&gt;: how many columns a tab should be made up of in the editor view.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;expandtab&lt;/code&gt;: when enabled, insert the appropriate number of spaces when in
insert mode.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shiftwidth&lt;/code&gt;: how many columns text will be indented when using indent
operations (such as &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; or &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;) in normal or visual mode&lt;/li&gt;
&lt;li&gt;&lt;code&gt;softtabstop&lt;/code&gt;: when enabled,
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;softtabstop&lt;/code&gt; &amp;lt; &lt;code&gt;tabstop&lt;/code&gt; &amp;amp;&amp;amp; &lt;code&gt;noexpandtab&lt;/code&gt;, this will result in a
combination of tabs and spaces to make up the total spacing .&lt;/li&gt;
&lt;li&gt;&lt;code&gt;softtabstop&lt;/code&gt; == &lt;code&gt;tabstop&lt;/code&gt; &amp;amp;&amp;amp; &lt;code&gt;noexpandtab&lt;/code&gt;, this will always force the
use of tabs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;expandtab&lt;/code&gt;, the value of &lt;code&gt;softtabstop&lt;/code&gt; will be ignored and spaces will be
forced&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shifround&lt;/code&gt;: round indent to nearest multiple of set &lt;code&gt;shiftwidth&lt;/code&gt; on indent
operations (&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; in Normal mode, &lt;code&gt;CTRL-T&lt;/code&gt; &lt;code&gt;CTRL-D&lt;/code&gt; in Insert mode)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Source: A byte of Lox (&lt;a href=&quot;https://federico-lox.github.io/development/tabs-stop-the-truth-about-vim-tab-spaces.html&quot;&gt;Tabs, stop! The truth about tab and spaces in Vim&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
</description>
       <pubDate>Fri, 18 Sep 2020 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/vim-indentation-options/</guid>
    </item>
    <item>
       <title>Today I troubleshot: Narrow non-breaking space not rendering</title>
       <link>https://morgan.cugerone.com/blog/troubleshooting-narrow-non-breaking-space-not-rendering/</link>
       <description>&lt;h2&gt;Trouble&lt;/h2&gt;
&lt;p&gt;Narrow non-breaking spaces (&lt;code&gt;&amp;amp;#8239;&lt;/code&gt;) would not render on a webpage.&lt;/p&gt;
&lt;h2&gt;First hint&lt;/h2&gt;
&lt;p&gt;I found out that the culprit was the &lt;code&gt;sans-serif&lt;/code&gt; font family in use.&lt;/p&gt;
&lt;h2&gt;Narrowing down the problem&lt;/h2&gt;
&lt;p&gt;After further investigation and especially &lt;a href=&quot;https://codepen.io/morgan/pen/mdPOXeN?editors=1000&quot;&gt;some tinkering on
Codepen&lt;/a&gt; I came to
these statements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;#8239;&lt;/code&gt; in &lt;code&gt;regular&lt;/code&gt; font type is &lt;strong&gt;rendered&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;#8239;&lt;/code&gt; in &lt;code&gt;italic&lt;/code&gt; font type style is &lt;strong&gt;rendered&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;#8239;&lt;/code&gt; in &lt;code&gt;bold&lt;/code&gt; font type is &lt;strong&gt;NOT rendered&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The third statements appears to me as a bug to be honest.&lt;/p&gt;
&lt;p&gt;Some googling brought me to this additional information:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In this case, narrow non-break space doesn&#39;t appear correctly because the
glyph (U+202F) doesn&#39;t exist in Georgia font.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Source: sumatrapdf issue tracker (&lt;a href=&quot;https://github.com/sumatrapdfreader/sumatrapdf/issues/1035#issuecomment-488748522&quot;&gt;&amp;quot;narrow non-break space&amp;quot; not displayed well in ePUB and PDF files&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;At this stage I realized that &lt;code&gt;sans-serif bold&lt;/code&gt; may also miss this glyph, and
that I will need to work around that.&lt;/p&gt;
&lt;h2&gt;Solution or rather workaround&lt;/h2&gt;
&lt;p&gt;First I thought about CSS, but it is impossible to style HTML entities like
&lt;code&gt;&amp;amp;#8239;&lt;/code&gt; because they are just characters.&lt;/p&gt;
&lt;p&gt;My final solution was to wrap this HTML entity around a HTML tag. I even created
a custom one for the occasion. Inspired by the &lt;code&gt;&amp;amp;nbsp;&lt;/code&gt; entity name, I came up
with the &lt;code&gt;&amp;lt;nnbsp&amp;gt;&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;The workaround is to assign &lt;code&gt;font-weight: normal;&lt;/code&gt; to this custom tag.&lt;br /&gt;
Of course I could have also come up with an utility class, but I found it take
more real estate in the code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This can only work if the &lt;code&gt;regular&lt;/code&gt; type for the font includes the
narrow non-breaking space glyph, what is the case for &lt;code&gt;sans-serif&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Example solution&lt;/h3&gt;
&lt;p&gt;HTML Markup:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;p class=&amp;quot;u-sans-serif&amp;quot;&amp;gt;
	&amp;lt;span class=&amp;quot;u-bold&amp;quot;&amp;gt;
		FIX Narrow non-breaking space issue&amp;lt;nnbsp&amp;gt;&amp;amp;#8239;&amp;lt;/nnbsp&amp;gt;!
	&amp;lt;/span&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Accompanying CSS:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.u-sans-serif {
	font-family: sans-serif;
}

.u-bold {
	font-weight: bold;
}

/* This is the workaround. */
nnbsp {
	font-weight: normal; /* Force Regular type rather than Bold. */
}
&lt;/code&gt;&lt;/pre&gt;
</description>
       <pubDate>Fri, 21 Aug 2020 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/troubleshooting-narrow-non-breaking-space-not-rendering/</guid>
    </item>
    <item>
       <title>Today I learned: How to tailor my `npm init` experience</title>
       <link>https://morgan.cugerone.com/blog/how-to-customize-your-npm-init-experience/</link>
       <description>&lt;p&gt;If you find yourself often creating &lt;code&gt;package.json&lt;/code&gt; files using the &lt;code&gt;npm init&lt;/code&gt;
command, there is a chance you would be pleased to know you can customize this process to your preferences and liking.&lt;/p&gt;
&lt;h2&gt;Creating an .npm-init.js file&lt;/h2&gt;
&lt;p&gt;Here is a straight forward way to do so:&lt;/p&gt;
&lt;p&gt;First off, create a file called &lt;code&gt;.npm-init.js&lt;/code&gt; in your home directory.&lt;/p&gt;
&lt;p&gt;Then edit this file, cherry picking from the below example, and adapting to your
liking and save it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const author = &#39;Captain Anonymous &#39;;

module.exports = {
	name: prompt(&#39;What awesome name should this module carry&#39;, &#39;legend&#39;),
	version: &#39;0.1.0&#39;,
	author: author,
	license: &#39;MIT&#39;,
	customField: &#39;Example custom field&#39;,
	otherCustomField: &#39;This example field is really cool&#39;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above example, we basically export the properties that will make up our
desired &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;prompt&lt;/code&gt; function is used to prompt the user with a question and its default
answer. Any other properties from the example will end up to be set with the
value, or the value of the variable, it is assigned with.&lt;/p&gt;
&lt;p&gt;Now, whenever you will use the &lt;code&gt;npm init&lt;/code&gt; command, you will get a much better
experience tailored to your need.&lt;/p&gt;
&lt;h2&gt;Custom npm init experience output&lt;/h2&gt;
&lt;p&gt;Below you can find the output generated from the &lt;code&gt;npm init&lt;/code&gt; command, using the
&lt;code&gt;.npm-init.js&lt;/code&gt; file from this blog post.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install &amp;lt;pkg&amp;gt;` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
What awesome name should this module carry: (legend)
About to write to /Users/captainanonymous/package.json:

{
  &amp;quot;name&amp;quot;: &amp;quot;legend&amp;quot;,
  &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;,
  &amp;quot;author&amp;quot;: &amp;quot;Captain Anonymous&amp;quot;,
  &amp;quot;license&amp;quot;: &amp;quot;MIT&amp;quot;,
  &amp;quot;customField&amp;quot;: &amp;quot;Example custom field&amp;quot;,
  &amp;quot;otherCustomField&amp;quot;: &amp;quot;This example field is really cool&amp;quot;
}


Is this OK? (yes)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Reference: Official npm documentation (&lt;a href=&quot;https://docs.npmjs.com/creating-a-package-json-file#running-a-cli-questionnaire&quot;&gt;Running a CLI questionnaire&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
</description>
       <pubDate>Fri, 07 Aug 2020 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/how-to-customize-your-npm-init-experience/</guid>
    </item>
    <item>
       <title>Today I learned: HTML input checkbox can have an indeterminate state</title>
       <link>https://morgan.cugerone.com/blog/html-input-checkbox-can-have-an-indeterminate-state/</link>
       <description>&lt;p&gt;As stated by the Mozilla Developer Network documentation,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;In addition to the checked and unchecked states, there is a third state a
checkbox can be in: &lt;strong&gt;indeterminate&lt;/strong&gt;.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the above, a checkbox refers to the HTML element &lt;code&gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; /&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Since I had never heard about it before in so many years of being a Web
developer, I thought it deserves a bit of spotlight.&lt;/p&gt;
&lt;h2&gt;Most common use case&lt;/h2&gt;
&lt;p&gt;In a hierarchical checkboxes structure, the &lt;code&gt;indeterminate&lt;/code&gt; state aims at
communicating, on a parent checkbox, that sub-items/sub-options are being
collected (checked).&lt;/p&gt;
&lt;h3&gt;Example: The grocery list&lt;/h3&gt;
&lt;p&gt;In upcoming list representations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[ ]&lt;/code&gt; represents an &lt;strong&gt;unchecked&lt;/strong&gt; checkbox&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[-]&lt;/code&gt; represents an &lt;strong&gt;undeterminate&lt;/strong&gt; checkbox&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[x]&lt;/code&gt; represents a &lt;strong&gt;checked&lt;/strong&gt; checkbox.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The below code block aim at representing the inital state of the list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ ] Fruits &amp;amp; veggies
	[ ] Apple
	[ ] Banana
	[ ] Cucumber
[ ] Dairy products
	[ ] Butter
	[ ] Milk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The below code block aims at representing a new state, e.g:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&amp;quot;Apple&amp;quot; is checked&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;Fruits &amp;amp; Veggies are being collected&amp;quot;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[-] Fruits &amp;amp; veggies
	[ ] Banana
	[x] Apple
	[ ] Cucumber
[ ] Dairy products
	[ ] Butter
	[ ] Milk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above scenario the user checked the &amp;quot;Apple&amp;quot; item.&lt;/p&gt;
&lt;p&gt;In order to communicate the state &lt;strong&gt;&amp;quot;Fruits &amp;amp; Veggies are being collected&amp;quot;&lt;/strong&gt;,
the &amp;quot;Fruits &amp;amp; Veggies&amp;quot; checkbox gets assigned an &lt;code&gt;indeterminate&lt;/code&gt; state.&lt;br /&gt;
Most browsers render this state using &amp;quot;a horizontal line in the box (it looks
somewhat like a hyphen or minus sign) instead of a check/tick&amp;quot;, just as we did
in the above code block.&lt;/p&gt;
&lt;h2&gt;Technical details and constraints&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;This can only be an enhancement, since the assignment of the &lt;code&gt;indeterminate&lt;/code&gt;
state can only be done by JavaScript.&lt;br /&gt;
There is not such thing as an &lt;code&gt;indeterminate&lt;/code&gt; property on the &lt;code&gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; /&amp;gt;&lt;/code&gt; HTML element, in comparison to the &lt;code&gt;checked&lt;/code&gt; state.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;inputInstance.indeterminate = true;&lt;/code&gt; is how you set that state in JavaScript,
where &lt;code&gt;inputInstance&lt;/code&gt; is an instance of the &lt;code&gt;HTMLInputElement&lt;/code&gt; JavaScript
object.&lt;/li&gt;
&lt;li&gt;At form submission, no data is sent to represent an &lt;code&gt;indeterminate&lt;/code&gt; checkbox.
Indeed, it is as if checkbox was not checked.&lt;/li&gt;
&lt;li&gt;Screen readers may consider the &lt;code&gt;indeterminate&lt;/code&gt; checkbox as not checked.&lt;br /&gt;
This is at least the case for &lt;strong&gt;Voice Over&lt;/strong&gt; at the time of writing.&lt;/li&gt;
&lt;li&gt;There is an &lt;code&gt;:indeterminate&lt;/code&gt; CSS pseudo class that can be used to target an
&lt;code&gt;indeterminate&lt;/code&gt; checkbox.&lt;br /&gt;
However, be wary! Indeed that &lt;code&gt;:indeterminate&lt;/code&gt; used alone would not only
match checkboxes, but could also match also &lt;code&gt;&amp;lt;input type=&amp;quot;radio&amp;quot;&amp;gt;&lt;/code&gt; elements
and &lt;code&gt;&amp;lt;progress&amp;gt;&lt;/code&gt; elements.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can &lt;a href=&quot;https://css-tricks.com/indeterminate-checkboxes/&quot;&gt;read more about the indeterminate checkboxes on CSS
Tricks&lt;/a&gt; where they present a
bunch of implementations and also another use case: &amp;quot;Rotating among the
states&amp;quot;.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Indeterminate_state_checkboxes&quot;&gt;Mozilla Developer Network article on Indeterminate state
checkboxes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://css-tricks.com/indeterminate-checkboxes/&quot;&gt;CSS Tricks article on Indeterminate
checkboxes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/:indeterminate&quot;&gt;Mozilla Developer Network article on :indeterminate CSS pseudo class&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
       <pubDate>Mon, 03 Aug 2020 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/html-input-checkbox-can-have-an-indeterminate-state/</guid>
    </item>
    <item>
       <title>Core principles of Progressive Enhancement</title>
       <link>https://morgan.cugerone.com/blog/progressive-enhancement-core-principles/</link>
       <description>&lt;p&gt;The progressive enhancement strategy consists of the following core principles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Basic content should be accessible to all web browsers&lt;/li&gt;
&lt;li&gt;Basic functionality should be accessible to all web browsers&lt;/li&gt;
&lt;li&gt;Sparse, semantic markup contains all content&lt;/li&gt;
&lt;li&gt;Enhanced layout is provided by externally linked CSS&lt;/li&gt;
&lt;li&gt;Enhanced behavior is provided by &lt;a href=&quot;https://en.wikipedia.org/wiki/Unobtrusive_JavaScript&quot;&gt;Unobtrusive JavaScript&lt;/a&gt;, externally linked JavaScript&lt;/li&gt;
&lt;li&gt;End-user web browser preferences are respected&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Source: Wikipedia (&lt;a href=&quot;https://en.wikipedia.org/wiki/Progressive_enhancement&quot;&gt;Progressive enhancement Wikipedia article&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
</description>
       <pubDate>Fri, 17 Apr 2020 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/progressive-enhancement-core-principles/</guid>
    </item>
    <item>
       <title>Fuzzy file search prompt ready upon vim entrance</title>
       <link>https://morgan.cugerone.com/blog/fuzzy-file-search-prompt-ready-upon-vim-entrance/</link>
       <description>&lt;p&gt;When I want to work on a project, I type &lt;code&gt;vim .&lt;/code&gt;, from my Terminal, in this
project&#39;s directory.&lt;/p&gt;
&lt;p&gt;This brings up &lt;a href=&quot;https://vimhelp.org/pi_netrw.txt.html#netrw-start&quot;&gt;Netrw&lt;/a&gt;, the default file explorer in Vim.&lt;/p&gt;
&lt;p&gt;In 90% of the time, I then fuzzy search the files I need to work on.&lt;/p&gt;
&lt;p&gt;Do you see some inefficiency here?&lt;br /&gt;
What if I could be prompted with the fuzzy file search, as soon as I enter Vim?&lt;/p&gt;
&lt;p&gt;Here is a little snippet I came up with and put in my &lt;code&gt;.vimrc&lt;/code&gt; file to enable
that.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function MyVimEnter()
    if argc() == 1 &amp;amp;&amp;amp; argv(0) == &#39;.&#39;
      execute &amp;quot;Files&amp;quot;
    endif

    return
endfunction
&amp;quot; The &#39;nested&#39; before call allows nested autocmds, important for
&amp;quot; syntax detection etc.
autocmd VimEnter * nested call MyVimEnter()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now in the other 10% of the time, I can just hit &lt;code&gt;Esc&lt;/code&gt; key to dismiss the Fuzzy
file search.&lt;/p&gt;
&lt;p&gt;In the fuzzy file search, in my case
&lt;a href=&quot;https://github.com/junegunn/fzf.vim&quot;&gt;FZF.vim&lt;/a&gt;, I can pick, using the &lt;code&gt;Tab&lt;/code&gt; key,
the few files I know will be working on and once ready hit &lt;code&gt;Enter&lt;/code&gt;, and boom I
have all the buffers I need to mess up with.&lt;/p&gt;
&lt;p&gt;I hope this gives you some lead to improve your &amp;quot;project entrance&amp;quot; workflow.&lt;/p&gt;
</description>
       <pubDate>Fri, 17 Apr 2020 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/fuzzy-file-search-prompt-ready-upon-vim-entrance/</guid>
    </item>
    <item>
       <title>Essential seeds</title>
       <link>https://morgan.cugerone.com/blog/essential-seeds/</link>
       <description>&lt;p&gt;As &lt;a href=&quot;https://twitter.com/rydercarroll&quot;&gt;Ryder Carroll&lt;/a&gt; states in his brilliant &lt;a href=&quot;https://bulletjournal.com/pages/book&quot;&gt;&amp;quot;The bullet
journal method&amp;quot; book&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The seed of passion is curiosity. The seed of perseverance is patience&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
       <pubDate>Thu, 25 Apr 2019 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/essential-seeds/</guid>
    </item>
    <item>
       <title>Progressive enhancement and rule of least power</title>
       <link>https://morgan.cugerone.com/blog/progressive-enhancement-and-rule-of-least-power/</link>
       <description>&lt;p&gt;Derek Featherstone stated:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;In the web front-end stack — HTML, CSS, JS, and ARIA — if you can solve a problem with a simpler solution lower in the stack, you should. It’s less fragile, more foolproof, and just works.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Source: Simply accessible (&lt;a href=&quot;https://simplyaccessible.com/article/data-attributes/&quot;&gt;Data attributes &amp;amp; progressive enhancement article&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
</description>
       <pubDate>Sat, 06 Apr 2019 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/progressive-enhancement-and-rule-of-least-power/</guid>
    </item>
    <item>
       <title>Initial post</title>
       <link>https://morgan.cugerone.com/blog/initial-post/</link>
       <description>&lt;p&gt;I picture this blog to be mostly technical but
there might be some life hack bits sneaking in at anytime.&lt;/p&gt;
&lt;p&gt;I wish to share my findings and learnings about things that I like i.e frontend
development, &lt;a href=&quot;https://inclusivedesignprinciples.info/&quot;&gt;inclusive design&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Web_accessibility&quot;&gt;Web
accessibility&lt;/a&gt;, my editor:
&lt;a href=&quot;https://www.vim.org/&quot;&gt;ViM&lt;/a&gt;, operating system and apps tips and tricks, &lt;a href=&quot;https://bulletjournal.com/&quot;&gt;bullet
journaling&lt;/a&gt;...&lt;/p&gt;
</description>
       <pubDate>Wed, 03 Apr 2019 00:00:00 +0000</pubDate>
       <guid isPermaLink='false'>https://morgan.cugerone.com/blog/initial-post/</guid>
    </item>
  </channel>
</rss>
