<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>TIL: Today I learned... on Brandon Pugh&#39;s Blog</title>
    <link>https://www.brandonpugh.com/til/</link>
    <description>Recent content in TIL: Today I learned... on Brandon Pugh&#39;s Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Thu, 21 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.brandonpugh.com/til/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>NPM 11.10.0 adds `min-release-age`</title>
      <link>https://www.brandonpugh.com/til/node/package-version-cooldown/</link>
      <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/node/package-version-cooldown/</guid>
      <description>&lt;p&gt;You can now specify a minimum age for installing package versions in NPM.&lt;/p&gt;
&lt;p&gt;This is a concept known as &lt;a href=&#34;https://cooldowns.dev/&#34;&gt;dependency cooldowns&lt;/a&gt; that has gained popularity with the rise in supply chain attacks.&lt;/p&gt;
&lt;p&gt;You need to be running at least &lt;a href=&#34;https://github.com/npm/cli/releases/tag/v11.10.0&#34;&gt;v11.10.0 of npm&lt;/a&gt; but then you can add the following to your &lt;code&gt;.npmrc&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-inf&#34; data-lang=&#34;inf&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;min-release-age&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or set it globally with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm config &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; min-release-age&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now NPM won&amp;rsquo;t install any package version that was released less than 7 days ago.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t specify a version, i.e. &lt;code&gt;npm install vite&lt;/code&gt;, then it will install the most recent version that satisfies the age requirement.&lt;/p&gt;
&lt;p&gt;If you specify a version that doesn&amp;rsquo;t meet the age requirement then it will error out.&lt;/p&gt;
&lt;p&gt;Note: if you&amp;rsquo;re running a version of NPM older than 11.10 then it will silently ignore the new config value.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/node/package-version-cooldown/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Insert the last argument of the previous terminal command</title>
      <link>https://www.brandonpugh.com/til/powershell/insert-last-argument/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/powershell/insert-last-argument/</guid>
      <description>&lt;p&gt;Today I learned that you can use &lt;code&gt;!$&lt;/code&gt; in bash to use the last argument of the previous command.&lt;/p&gt;
&lt;p&gt;The simplest example is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mkdir /some/long/path
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; !$
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can do something similar in powershell by using a PSReadline binding:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Set-PSReadLineKeyHandler&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Chord&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Alt+.&amp;#34;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;YankLastArg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/powershell/insert-last-argument/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Display git commit dates in local timezone</title>
      <link>https://www.brandonpugh.com/til/git/display-local-date/</link>
      <pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/display-local-date/</guid>
      <description>&lt;p&gt;Most Git commands accept a &lt;code&gt;--date=&lt;/code&gt; option with accepted values of &lt;code&gt;relative&lt;/code&gt;, &lt;code&gt;local&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;iso&lt;/code&gt;, or &lt;code&gt;rfc&lt;/code&gt; to control how dates are displayed.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git show --date&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And as usual, if you Git to always display dates this way then you can set it globally with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git config --global log.date &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/display-local-date/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>List installed node versions with Volta</title>
      <link>https://www.brandonpugh.com/til/node/volta-list/</link>
      <pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/node/volta-list/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://volta.sh/&#34;&gt;Volta&lt;/a&gt; is my preferred node version manager these days but the commands are a bit different to what I&amp;rsquo;m used to.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;volta list&lt;/code&gt; - show the current tool versions in use&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volta list node&lt;/code&gt; - show all the versions of node downloaded to the machine&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volta install node@version&lt;/code&gt; - use the specified version of node. It will download and install it if hasn&amp;rsquo;t before otherwise it will just select it (there is no separate &lt;code&gt;use&lt;/code&gt; command).&lt;/li&gt;
&lt;/ul&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/node/volta-list/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Enable markdown in Google Docs</title>
      <link>https://www.brandonpugh.com/til/google/docs-enable-markdown/</link>
      <pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/google/docs-enable-markdown/</guid>
      <description>&lt;p&gt;Today I learned that you can &lt;a href=&#34;https://support.google.com/docs/answer/12014036?hl=en&#34;&gt;enable markdown&lt;/a&gt; in Google Docs.&lt;/p&gt;
&lt;p&gt;This isn&amp;rsquo;t really &lt;em&gt;full&lt;/em&gt; markdown support but it does make interoperating with markdown easier.&lt;/p&gt;
&lt;p&gt;The best feature is it enables the &amp;ldquo;Paste from markdown&amp;rdquo; right-click option.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/google/docs-enable-markdown/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Rebuilding a 6v Power Wheels battery</title>
      <link>https://www.brandonpugh.com/til/electronics/rebuild-powerwheels-battery/</link>
      <pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/electronics/rebuild-powerwheels-battery/</guid>
      <description>&lt;p&gt;We bought the &amp;ldquo;Fisher-Price Thomas &amp;amp; Friends Ride-On Train&amp;rdquo; for our toddler, and after some time, the battery stopped charging.
It uses a Power Wheels 6V 2400 mAh NiMH battery (Model No. 1102822518 / Part No. 3900-8218).
Apparently, this battery was fairly unique (and &lt;a href=&#34;https://www.amazon.com/product-reviews/B09P9LWMZY/ref=acr_dp_hist_1?ie=UTF8&amp;amp;filterByStar=one_star&amp;amp;reviewerType=all_reviews#reviews-filter-bar&#34;&gt;problematic&lt;/a&gt;) to this toy and has since been &lt;a href=&#34;https://www.impactbattery.com/power-wheels-nimh-6-volt-2400-mah-battery-1102822518-for-thomas-hhp26.html&#34;&gt;discontinued&lt;/a&gt;.
&lt;img alt=&#34;alt text&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/rebuild-powerwheels-battery-product-image.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;I, of course, did not want to scrap an entire Power Wheels toy that worked just fine except for the battery.&lt;/p&gt;
&lt;p&gt;One thing I will say about it, though, is that it&amp;rsquo;s surprisingly repairable.
I was able to open it up just by removing four Phillips screws.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;alt text&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/rebuild-powerwheels-battery-opened.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;From what I gathered, the circuit board is what makes this battery unique.
It allows charging the NiMH battery via micro-USB instead of the typical Power Wheels charger.&lt;/p&gt;
&lt;p&gt;All of the wires seemed fairly self-explanatory, except for two small additional wires coming from the battery pack.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;alt text&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/rebuild-powerwheels-battery-circuit-board-wires.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;Well, it turns out these 6V battery packs are just five rechargeable AA batteries strapped together.
The wires were just going to a small thermistor to measure the temperature of the batteries as a way to gauge how much it&amp;rsquo;s charged.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;alt text&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/rebuild-powerwheels-battery-stripped-battery-pack.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;After that, all I had to do was desolder the battery pack from the board, buy a replacement, solder it to the board, and tape the thermistor to the new pack.
Then I sealed it all back up and I was good to go!&lt;/p&gt;
&lt;p&gt;I did come across a &lt;a href=&#34;https://batterygiantaz.com/products/3900-8218-6v-black-thomas-the-train-battery-new-style-rebuild-service&#34;&gt;service&lt;/a&gt; that seems to do this for you, but it turned out to be fairly straightforward to do it myself.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/electronics/rebuild-powerwheels-battery/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>datetime-local doesn&#39;t have full cross-browser support</title>
      <link>https://www.brandonpugh.com/til/html/datetime-local-support/</link>
      <pubDate>Sun, 04 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/datetime-local-support/</guid>
      <description>&lt;p&gt;I recently discovered the &lt;code&gt;datetime-local&lt;/code&gt; input type doesn&amp;rsquo;t actually have full browser support.&lt;/p&gt;
&lt;p&gt;If you have a form value that needs both a date and time component, then you might be tempted to rely on the platform to simplify your implementation and use &lt;code&gt;datetime-local&lt;/code&gt; to avoid needing two separate inputs, the values of which you&amp;rsquo;ll need to combine at some point. Unfortunately I don&amp;rsquo;t think it&amp;rsquo;s supported enough to be usable in most applications.&lt;/p&gt;
&lt;p&gt;The MDN page for &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/datetime-local&#34;&gt;datetime-local&lt;/a&gt; is a bit misleading because at the top it says it&amp;rsquo;s &amp;ldquo;Baseline widely available&amp;rdquo; but if you check the browser &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/datetime-local#browser_compatibility&#34;&gt;compatibility chart&lt;/a&gt; down at the bottom then you&amp;rsquo;ll see asterisks next to Firefox and Safari on Desktop and clicking that reveals that they only display a datepicker and &lt;em&gt;not&lt;/em&gt; a timepicker.&lt;/p&gt;
&lt;p&gt;This means that users have to manually type in the time which &lt;em&gt;might&lt;/em&gt; be an acceptable tradeoff but if the user doesn&amp;rsquo;t add the time then Firefox will just return &lt;code&gt;null&lt;/code&gt; as its value.&lt;/p&gt;
&lt;p&gt;Firefox did recently address these issues in Firefox 144, but as of this writing it&amp;rsquo;s still behind an &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Experimental_features#time_picker_for_datetime-local_input_field&#34;&gt;experimental flag&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot firefox new support&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/html/firefox-datetime-local-support.png&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/datetime-local-support/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Splice wires with solder seal connectors</title>
      <link>https://www.brandonpugh.com/til/electronics/solder-seal-wires/</link>
      <pubDate>Fri, 12 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/electronics/solder-seal-wires/</guid>
      <description>&lt;p&gt;After setting the Christmas tree this, a section of the builtin lights weren&amp;rsquo;t turning on and found two of the wires had been chewed through.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;broken wires&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/solder-seal-wires-before.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t want to have to throw out the whole tree so I set about fixing it.
I wasn&amp;rsquo;t looking forward to it though as I thought I would have to solder the wires together and cover them with heat shrink tubing&amp;hellip; a process that was going to be &lt;em&gt;very&lt;/em&gt; annoying under a Christmas tree.
I debated just taping them together with some electrical tape but I didn&amp;rsquo;t want to deal with it maybe coming loose while taking it in and out of storage.&lt;/p&gt;
&lt;p&gt;Fortunately while googling for some tips, I came across these &lt;a href=&#34;https://www.amazon.com/dp/B073RMRCC3&#34;&gt;solder seal wire connectors&lt;/a&gt; which made the process a whole lot easier.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;fixed wires with connectors&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/PXL_20251214_181618938.webp&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/electronics/solder-seal-wires/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Fix &#39;value&#39; does not exist on type &#39;HTMLElement&#39;</title>
      <link>https://www.brandonpugh.com/til/react/value-does-not-exist-html-element/</link>
      <pubDate>Sat, 29 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/react/value-does-not-exist-html-element/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s common to see the error &lt;code&gt;Property &#39;value&#39; does not exist on type &#39;HTMLElement&#39;&lt;/code&gt; when working with react testing library.&lt;/p&gt;
&lt;p&gt;Common advice online is to cast result using the &lt;code&gt;as&lt;/code&gt; operator.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;title&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;getByPlaceholderText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;HTMLInputElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is fine but feels incorrect and when using &lt;a href=&#34;https://typescript-eslint.io/rules/no-unnecessary-type-assertion/&#34;&gt;eslint-typescript&lt;/a&gt; will complain that the cast is unnecessary: &lt;code&gt;This assertion is unnecessary since it does not change the type of the expression&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Then, thanks to this &lt;a href=&#34;https://stackoverflow.com/a/70794857/1715138&#34;&gt;SO answer&lt;/a&gt;, I learned that the react testing library query methods can now take an optional type parameter:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;screen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getByLabelText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;HTMLInputElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This feels much cleaner and makes both the linter and compiler happy.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/react/value-does-not-exist-html-element/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Sessions don&#39;t end when the browser closes</title>
      <link>https://www.brandonpugh.com/til/chrome/session-cookies/</link>
      <pubDate>Wed, 12 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/chrome/session-cookies/</guid>
      <description>&lt;p&gt;There seems to be a common misunderstanding about how session cookies usually work.&lt;/p&gt;
&lt;p&gt;Closing the browser doesn&amp;rsquo;t necessarily clear out session cookies because the user can have the option of &amp;ldquo;Continue where you left off&amp;rdquo; enabled for Chrome startup.
Folks usually enable this if they don&amp;rsquo;t want to lose their open tabs when Chrome closes, but Chrome also continues the session so session cookies could potentially persist indefinitely.&lt;/p&gt;
&lt;p&gt;So if a user is having issues related to a site&amp;rsquo;s cookies, the most reliable solution is having them delete the cookies for this site.
You can get to that fairly easily by clicking the settings icon on the left side of the address bar.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of the chrome site settings menu&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/chrome/chrome-site-settings-screenshot.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;That takes them to the settings page with a button at the top to delete all the data for that specific site.&lt;/p&gt;
&lt;p&gt;You can also copy/paste this in the address bar to go directly there for a specific site (replace &lt;code&gt;stackoverflow.com&lt;/code&gt; with your actual site): &lt;code&gt;chrome://settings/content/siteDetails?site=https%3A%2F%2Fstackoverflow.com&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This &lt;a href=&#34;https://stackoverflow.com/questions/10617954/chrome-doesnt-delete-session-cookies&#34;&gt;Stack Overflow question&lt;/a&gt; shows that this isn&amp;rsquo;t how a lot of people expect it to behave.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/chrome/session-cookies/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Import external stylesheet into a layer</title>
      <link>https://www.brandonpugh.com/til/css/import-stylesheet-layer/</link>
      <pubDate>Wed, 22 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/import-stylesheet-layer/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m working on a legacy project that&amp;rsquo;s stuck on v3 of bootstrap and just loads the full minified css file.
We wanted to make it a bit easier to override some of the builtin styles and figured that the new &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@layer&#34;&gt;@layer&lt;/a&gt; feature of CSS would be perfect.&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t want to change too much about the stylesheets were aren&amp;rsquo;t and thankfully it turns out you can import a stylesheet into a layer:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://ourcdn.com/content/css/bootstrap.min.css&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&amp;lt;!-- becomes ↓↓↓ --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://ourcdn.com/content/css/bootstrap.min.css&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;layer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bootstrap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The main downside is the &lt;code&gt;@import&lt;/code&gt; rule doesn&amp;rsquo;t support &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Subresource_Integrity&#34;&gt;Subresource Integrity&lt;/a&gt; so you&amp;rsquo;ll want to make sure it&amp;rsquo;s a trusted source.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/import-stylesheet-layer/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Lowercase head behaves differently in git worktrees</title>
      <link>https://www.brandonpugh.com/til/git/head-is-case-sensitive/</link>
      <pubDate>Sat, 11 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/head-is-case-sensitive/</guid>
      <description>&lt;p&gt;Today I discovered that referencing &lt;code&gt;HEAD&lt;/code&gt; in git commands should technically always be uppercase.&lt;/p&gt;
&lt;p&gt;On case-insensitive file systems you can use lowercase &lt;code&gt;head&lt;/code&gt; most of the time and it just works&amp;hellip; as long as you don&amp;rsquo;t use worktrees.&lt;/p&gt;
&lt;p&gt;If you use &lt;code&gt;head&lt;/code&gt; while in a worktree then it resolves to the head of the &lt;em&gt;main&lt;/em&gt; worktree and not the head of the worktree you&amp;rsquo;re currently in like you would expect.&lt;/p&gt;
&lt;p&gt;I learned this the hard way after getting some very confusing results from the git command I was running.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/48137927/git-head-lowercase-vs-head-uppercase/56346962#56346962&#34;&gt;This Stackoverflow answer&lt;/a&gt; explains exactly why it happens and gives the very sensible advice to &amp;ldquo;Avoid this bad habit: if you don&amp;rsquo;t like typing &lt;code&gt;HEAD&lt;/code&gt; in all uppercase, use &lt;code&gt;@&lt;/code&gt;&amp;rdquo;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/head-is-case-sensitive/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>You can use C# records in .NET Framework 4.x</title>
      <link>https://www.brandonpugh.com/til/csharp/records-framework-4x/</link>
      <pubDate>Sat, 20 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/csharp/records-framework-4x/</guid>
      <description>&lt;p&gt;Today I learned that you can use C# records that were introduced in C# 9 even if you&amp;rsquo;re not on .NET Core yet.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.ndepend.com/using-c9-record-and-init-property-in-your-net-framework-4-x-net-standard-and-net-core-projects/&#34;&gt;NDepend has a post&lt;/a&gt; on how to do this which is slightly more involved.&lt;/p&gt;
&lt;p&gt;But per this &lt;a href=&#34;https://stackoverflow.com/a/65663416/1715138&#34;&gt;Stack Overflow answer&lt;/a&gt;, all I did was add a file with the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cs&#34; data-lang=&#34;cs&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;System.Runtime.CompilerServices&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;internal&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;IsExternalInit&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and that worked.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been using them in unit tests like &lt;a href=&#34;https://josef.codes/using-records-when-implementing-the-builder-pattern-in-c-sharp/&#34;&gt;this post&lt;/a&gt; describes.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/csharp/records-framework-4x/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>You can backup your git stashes</title>
      <link>https://www.brandonpugh.com/til/git/backup-stashes/</link>
      <pubDate>Fri, 29 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/backup-stashes/</guid>
      <description>&lt;p&gt;As of Git &lt;a href=&#34;https://github.blog/open-source/git/highlights-from-git-2-51/&#34;&gt;2.51&lt;/a&gt; there is now a process for backing up your git stashes.&lt;/p&gt;
&lt;p&gt;The gist of it is there is now &lt;code&gt;stash export&lt;/code&gt; command to export your stashes as a single reference and push them to a remote:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git stash &lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; --to-ref refs/stashes/my-stash
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git push origin refs/stashes/my-stash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and then on another machine or a different clone of the repo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git fetch origin &lt;span class=&#34;s1&#34;&gt;&amp;#39;+refs/stashes/*:refs/stashes/*&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git stash import refs/stashes/my-stash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unfortunately this process isn&amp;rsquo;t that great for regular backups but can be useful if you need easily move lots stashes to another machine.
For one off stashes though, it might be easier to create a &lt;a href=&#34;https://www.brandonpugh.com/til/git/apply-patch/&#34;&gt;patch file&lt;/a&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/backup-stashes/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>ICS end dates are exclusive</title>
      <link>https://www.brandonpugh.com/til/google/ics-end-dates-exclusive/</link>
      <pubDate>Tue, 05 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/google/ics-end-dates-exclusive/</guid>
      <description>&lt;p&gt;Today I learned that per the spec, the &lt;code&gt;DTEND&lt;/code&gt; value in an ICS file is &lt;em&gt;exclusive&lt;/em&gt; for all-day events.&lt;/p&gt;
&lt;p&gt;It makes sense but it&amp;rsquo;s &lt;em&gt;not&lt;/em&gt; how most people think of date ranges.&lt;/p&gt;
&lt;p&gt;I ran into this while making a small node script that takes a json array of events and generates an ICS file.
This has been the most convenient way I&amp;rsquo;ve found to quickly bulk create events in Google Calendar.
The only issue is the multi-day events were coming up a day short.&lt;/p&gt;
&lt;p&gt;So for example if Spring Break is from March 16th - March 20th, then the end date would need to be March 21st:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-inf&#34; data-lang=&#34;inf&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;DTSTART;VALUE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;DATE:20260316&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;DTEND;VALUE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;DATE:20260321&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pro tip: if you&amp;rsquo;re importing a lot of events into Google Calendar, create a brand new &amp;ldquo;test&amp;rdquo; calendar and import the &lt;code&gt;.ics&lt;/code&gt; file into that calendar first to test it out that way if something is messed up you can just delete the calendar and try again.
Otherwise you have to go through and manually find all the events that got added.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/google/ics-end-dates-exclusive/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Apply a patch file</title>
      <link>https://www.brandonpugh.com/til/git/apply-patch/</link>
      <pubDate>Tue, 22 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/apply-patch/</guid>
      <description>&lt;p&gt;Today I learned how to create and apply a patch file with Git.&lt;/p&gt;
&lt;p&gt;If you want to quickly create patch a file from your current changes just run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git diff &amp;gt; mypatch.patch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or if like me you just want specific changes then stage them and then run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git diff --cached &amp;gt; mypatch.patch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;then to apply the changes all you need is &lt;code&gt;git apply mychanges.patch&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately if there are conflicts then git will just give you an error: &lt;code&gt;patch does not apply&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I found if you add the following parameters it&amp;rsquo;ll be more likely to apply cleanly and if not then it&amp;rsquo;ll add conflict markers to the files and you can try to fix the conflicts and generate a new patch:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git apply --3way --ignore-space-change --ignore-whitespace mychanges.patch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve been using this as a more convenient way to frequently re-apply changes I need locally compared to something like &lt;a href=&#34;https://www.brandonpugh.com/til/git/skip-worktree-ignore-modified-files/&#34;&gt;&lt;code&gt;--skip-worktree&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve also found it convenient for sending some quick changes to a teammate.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/apply-patch/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Share git configuration in repo</title>
      <link>https://www.brandonpugh.com/til/git/share-git-config-repo/</link>
      <pubDate>Sat, 12 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/share-git-config-repo/</guid>
      <description>&lt;p&gt;Today I learned that you can share a git config file in a repository for easily sharing certain local config settings with your team.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git config --local include.path ../.gitconfig
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This adds the following to your local &lt;code&gt;config&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-properties&#34; data-lang=&#34;properties&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;[include]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;../.gitconfig&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and will load any config values set in that file.&lt;/p&gt;
&lt;p&gt;This has a couple advantages in that we only have to run a single git
command and if we need to make future changes we only have to update the
config file instead of requiring devs to run additional commands to get
the update.&lt;/p&gt;
&lt;p&gt;These are a couple of common settings I use on a team:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-properties&#34; data-lang=&#34;properties&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;[core]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;hooksPath&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;./src/git-hooks/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;[blame]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;ignoreRevsFile&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;.git-blame-ignore-revs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/share-git-config-repo/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Quickly Fix A Misspelled Word</title>
      <link>https://www.brandonpugh.com/til/vim/quickly-fix-misspelled-word/</link>
      <pubDate>Sun, 06 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/quickly-fix-misspelled-word/</guid>
      <description>&lt;p&gt;I just learned that you can have automatically fix a misspelled word with the top suggestion by typing:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-vim&#34; data-lang=&#34;vim&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;z&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is opposed to the regular &lt;code&gt;z=&lt;/code&gt; command for opening the regular list of spelling correction options.&lt;/p&gt;
&lt;p&gt;Like &lt;a href=&#34;https://github.com/jbranchaud/til/blob/master/vim/quickly-fix-a-misspelled-word.md&#34;&gt;Josh&lt;/a&gt; who I learned this from, I usually pick the first option so this is a bit more convenient.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/quickly-fix-misspelled-word/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Sudo for Windows</title>
      <link>https://www.brandonpugh.com/til/windows/sudo-for-windows/</link>
      <pubDate>Wed, 25 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/windows/sudo-for-windows/</guid>
      <description>&lt;p&gt;I just learned that Windows now has a builtin &lt;code&gt;sudo&lt;/code&gt; command.
You need to enable it from the Windows developer settings and then you use it similar to &lt;code&gt;sudo&lt;/code&gt; on other operating systems.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been using &lt;a href=&#34;https://gerardog.github.io/gsudo/docs/gsudo-vs-sudo&#34;&gt;gsudo&lt;/a&gt; for some time and I still prefer as it overall has a nicer experience and is more fully featured, but if you&amp;rsquo;re looking for one less thing to install then the builtin sudo is decent.&lt;/p&gt;
&lt;p&gt;One thing I ran into though is in the default &amp;ldquo;new window&amp;rdquo; mode, if you want to run a powershell script elevated then you need to run it as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sudo&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pwsh&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;ps1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/windows/sudo-for-windows/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use skip-worktree to ignore modified files</title>
      <link>https://www.brandonpugh.com/til/git/skip-worktree-ignore-modified-files/</link>
      <pubDate>Fri, 20 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/skip-worktree-ignore-modified-files/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;code&gt;--skip-worktree&lt;/code&gt; command in git which will treat a file like it hasn&amp;rsquo;t been modified.
This is useful if you have to modify a file locally but don&amp;rsquo;t ever want to commit it (config files are a common scenario).&lt;/p&gt;
&lt;p&gt;Like me, you may have seen &lt;code&gt;--assume-unchanged&lt;/code&gt; used in this way but that&amp;rsquo;s not what it&amp;rsquo;s meant for since it&amp;rsquo;s &amp;ldquo;designed for cases where it is expensive to check whether a group of files have been modified&amp;rdquo;.
As a result you&amp;rsquo;re likely to lose the changes you have made to those files.
&lt;a href=&#34;https://web.archive.org/web/20200604104042/http://fallengamer.livejournal.com/93321.html&#34;&gt;This post&lt;/a&gt; shows a good summary of the outcomes of common operations with each command.&lt;/p&gt;
&lt;p&gt;The advantage of &lt;code&gt;--skip-worktree&lt;/code&gt; is that git really tries to preserve the changes you&amp;rsquo;ve made to those files.
This works pretty well if the files aren&amp;rsquo;t changed very often but it can be pretty tedious if they change frequently even when those changes wouldn&amp;rsquo;t have caused merge conflicts as git will refuse to modify the files.&lt;/p&gt;
&lt;p&gt;Say for example you need to make a change to a config file for your environment. You would run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git update-index --skip-worktree config/local.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If changes are rarely committed to this than you may not have to think about it again.&lt;/p&gt;
&lt;p&gt;However, if you need to switch to a branch with changes to this file then you&amp;rsquo;ll get an error like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;error: Your local changes to the following files would be overwritten by checkout:
path/to/file&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you run &lt;code&gt;git stash&lt;/code&gt; now, that file won&amp;rsquo;t be affected.&lt;/p&gt;
&lt;p&gt;So now you need to run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git update-index --no-skip-worktree config/local.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# now you can run stash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git stash
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git switch other-branch
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git stash pop
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# you&amp;#39;ll need to resolve conflicts if any otherwise skip the file again&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git update-index --skip-worktree config/local.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# you can run this to see which files have skip-worktree set&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git ls-files -v &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep &lt;span class=&#34;s1&#34;&gt;&amp;#39;^S&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Depending on how frequently you have to deal with this, you&amp;rsquo;ll quickly end up making an alias or script for it.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/skip-worktree-ignore-modified-files/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Quickly react to recent message in Slack</title>
      <link>https://www.brandonpugh.com/til/writing/react-recent-slack-message/</link>
      <pubDate>Wed, 18 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/writing/react-recent-slack-message/</guid>
      <description>&lt;p&gt;Today I learned that you can react to the most recent message just by adding &lt;code&gt;+&lt;/code&gt;.
So you can type &lt;code&gt;+:thumbsup:&lt;/code&gt; as the message it add it as a reaction to the most recent message instead of an individual message.&lt;/p&gt;
&lt;p&gt;You can also type &lt;code&gt;⌘⇧\&lt;/code&gt; or &lt;code&gt;ctrl⇧\&lt;/code&gt; to open the emoji picker on the message.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/writing/react-recent-slack-message/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Move a line with :m</title>
      <link>https://www.brandonpugh.com/til/vim/move-line/</link>
      <pubDate>Tue, 17 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/move-line/</guid>
      <description>&lt;p&gt;Today I learned that you can move the current line up or down with &lt;code&gt;:m&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;:m +1 - moves down 1 line&lt;/p&gt;
&lt;p&gt;:m -2 - move up 2 lines&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m used to using &lt;code&gt;dd&lt;/code&gt; followed by a movement and then &lt;code&gt;p&lt;/code&gt; but I may try this alternate method.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/move-line/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Install SQL Server from the command line</title>
      <link>https://www.brandonpugh.com/til/sql-server/install-from-cli/</link>
      <pubDate>Fri, 06 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/sql-server/install-from-cli/</guid>
      <description>&lt;p&gt;I recently had to setup a new windows dev machine with a local instance of SQL Server and it turns out you can run it completely from the command line although it&amp;rsquo;s not very obvious how.&lt;/p&gt;
&lt;p&gt;Once you &lt;a href=&#34;https://www.microsoft.com/en-us/sql-server/sql-server-downloads&#34;&gt;download the installer&lt;/a&gt; it will extract everything to a folder which contains the &lt;code&gt;SETUP.exe&lt;/code&gt; executable which you can run from the terminal and pass all the options you want instead of clicking through the UI.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re like me and just needed a fairly standard installation for local development, then this should do it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SETUP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;EXE&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IACCEPTSQLSERVERLICENSETERMS&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ACTION&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;install&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEATURES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SQLEngine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FullText&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INSTANCENAME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MSSQLSERVER&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SQLSYSADMINACCOUNTS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$env:USERDOMAIN&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$env:USERNAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SQLSVCACCOUNT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;NT Service\MSSQLSERVER&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AGTSVCACCOUNT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;NT Service\SQLSERVERAGENT&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SQLSVCINSTANTFILEINIT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;True&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INDICATEPROGRESS&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Q&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Management studio is no longer included with the main installer but you can use winget: &lt;code&gt;winget install -e --id Microsoft.SQLServerManagementStudio&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you need additional features then you need to &lt;a href=&#34;https://learn.microsoft.com/en-us/sql/database-engine/install-windows/install-sql-server-from-the-command-prompt?view=sql-server-ver17#Feature&#34;&gt;look up&lt;/a&gt; the options to set on the &lt;code&gt;/FEATURES&lt;/code&gt; param, like &lt;code&gt;RS&lt;/code&gt; for reporting services.&lt;/p&gt;
&lt;h2 id=&#34;details&#34;&gt;Details&lt;/h2&gt;
&lt;p&gt;This is what the above command does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/IACCEPTSQLSERVERLICENSETERMS&lt;/code&gt; - Required to accept the SQL Server license terms.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/Q&lt;/code&gt; - Runs setup in &lt;strong&gt;quiet mode&lt;/strong&gt;. This is needed otherwise it will just open the regular install UI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/ACTION=&amp;quot;install&amp;quot;&lt;/code&gt; - Specify that we want to install vs uninstall or upgrade.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/FEATURES=SQLEngine,FullText&lt;/code&gt; - Specify which SQL Server components to install:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SQLEngine&lt;/strong&gt;: The core database engine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FullText&lt;/strong&gt;: Full-text search&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/INSTANCENAME=&amp;quot;MSSQLSERVER&amp;quot;&lt;/code&gt; - &lt;code&gt;&amp;quot;MSSQLSERVER&amp;quot;&lt;/code&gt; is the &lt;strong&gt;default instance name&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/SQLSYSADMINACCOUNTS=&amp;quot;$env:USERDOMAIN\$env:USERNAME&amp;quot;&lt;/code&gt; - Use powershell environment variables to set the current user as the sql server admin&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/SQLSVCACCOUNT=&amp;quot;NT Service\MSSQLSERVER&amp;quot;&lt;/code&gt; - Set the service account for the SQL Server Database Engine service. &lt;code&gt;&amp;quot;NT Service\MSSQLSERVER&amp;quot;&lt;/code&gt; is the common default when using the UI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/AGTSVCACCOUNT=&amp;quot;NT Service\SQLSERVERAGENT&amp;quot;&lt;/code&gt; - Sets the account for the &lt;strong&gt;SQL Server Agent service&lt;/strong&gt; (handles scheduled jobs and alerts)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/SQLSVCINSTANTFILEINIT=True&lt;/code&gt; - Enables &lt;a href=&#34;https://learn.microsoft.com/en-us/sql/relational-databases/databases/database-instant-file-initialization&#34;&gt;&lt;strong&gt;Instant File Initialization&lt;/strong&gt;&lt;/a&gt;, which seems like a worthwhile performance optimization according to the docs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/INDICATEPROGRESS&lt;/code&gt; - Shows installation progress in the console window, useful for monitoring the installation status&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, you can apparently install from a &lt;a href=&#34;https://learn.microsoft.com/en-us/sql/database-engine/install-windows/install-sql-server-using-a-configuration-file?view=sql-server-ver17&amp;amp;source=recommendations&#34;&gt;configuration file&lt;/a&gt; that the installer can generate for you.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/sql-server/install-from-cli/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use winget to install Git for Windows with Unix tools</title>
      <link>https://www.brandonpugh.com/til/windows/winget-git/</link>
      <pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/windows/winget-git/</guid>
      <description>&lt;p&gt;For years I&amp;rsquo;ve been using Chocolately for quickly installing git on new Windows and it&amp;rsquo;s pretty handy.
Recently though I looked into doing the same with winget since it comes built into Windows now which makes it easier to just give to the command to a co-worker.&lt;/p&gt;
&lt;p&gt;One thing I always do though is enable the option to add the common linux tools to the path.&lt;/p&gt;
&lt;p&gt;With Chocolately you could just add the &lt;code&gt;/GitAndUnixToolsOnPath&lt;/code&gt; param like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;choco install git.install -y --params=&amp;quot;&#39;/GitAndUnixToolsOnPath&#39;&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It turns out that is a convenience option added to the chocolately package so it took a bit of digging to figure out how do it with winget but I eventually arrived at the following:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;winget install --id Git.Git -e --source winget --custom &#39;/o:PathOption=CmdTools&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You need the &lt;code&gt;--custom&lt;/code&gt; param for the &lt;a href=&#34;https://learn.microsoft.com/en-us/windows/package-manager/winget/install&#34;&gt;install command&lt;/a&gt; that let&amp;rsquo;s you pass arguments to the git installer.&lt;/p&gt;
&lt;p&gt;Then I just had to reference the handy &lt;a href=&#34;https://gitforwindows.org/silent-or-unattended-installation.html&#34;&gt;docs for the installer&lt;/a&gt; for git for windows and find which &lt;a href=&#34;https://gitforwindows.org/mapping-between-git-installer-gui-settings-and-command-line-arguments.html&#34;&gt;arguments&lt;/a&gt; corresponded to the options I wanted. &lt;code&gt;PathOption=CmdTools&lt;/code&gt; in this case.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/windows/winget-git/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Auto add pull request reviewers</title>
      <link>https://www.brandonpugh.com/til/azure-devops/auto-add-reviewers/</link>
      <pubDate>Tue, 03 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/azure-devops/auto-add-reviewers/</guid>
      <description>&lt;p&gt;Today I learned that Azure DevOps lets you &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops&amp;amp;tabs=browser#automatically-include-code-reviewers&#34;&gt;automatically include reviewers&lt;/a&gt; for a pull request if modifies certain files.&lt;/p&gt;
&lt;p&gt;This is very similar to Github&amp;rsquo;s &lt;a href=&#34;https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners&#34;&gt;code owners&lt;/a&gt; file with the key difference being that you configure it through the repo setting in Azure DevOps instead of committing a file.&lt;/p&gt;
&lt;p&gt;I find this very useful for example if you&amp;rsquo;re a Front End Architect who wants to be aware of any changes to the UI or if you&amp;rsquo;re a DBA who wants to review any database migrations.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/azure-devops/auto-add-reviewers/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Link directly to a VS code setting</title>
      <link>https://www.brandonpugh.com/til/vscode/link-to-setting/</link>
      <pubDate>Sat, 03 May 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/link-to-setting/</guid>
      <description>&lt;p&gt;Today I learned that you can link directly to specific VS Code settings using the &lt;code&gt;vscode:&lt;/code&gt; URL scheme.
They follow this format: &lt;code&gt;vscode://settings/editor.formatOnSave&lt;/code&gt;, where you put the setting ID at the end of the URL.&lt;/p&gt;
&lt;p&gt;So if you click &lt;a href=&#34;#ZgotmplZ&#34;&gt;this link&lt;/a&gt;, VS Code should open straight to that setting.&lt;/p&gt;
&lt;p&gt;This is probably most useful for folks who like to write about VS Code features (like me), but it&amp;rsquo;s also handy if you&amp;rsquo;re helping like a teammate you can just send them a link to a setting to make it easier for them.&lt;/p&gt;
&lt;p&gt;Also, in VS Code, you can click the gear icon next to a setting and select &amp;ldquo;Copy Setting URL&amp;rdquo; to get the link.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/link-to-setting/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Fixing a bunny led night light</title>
      <link>https://www.brandonpugh.com/til/electronics/fix-bunny-led/</link>
      <pubDate>Fri, 25 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/electronics/fix-bunny-led/</guid>
      <description>&lt;p&gt;This effectively amounted to replacing a battery but I still learned some things along the way.&lt;/p&gt;
&lt;p&gt;It was thankfully easy to take the rubber case off which I expected to be glued or something but I just had to pull it off.&lt;/p&gt;
&lt;p&gt;This revealed the main board with the LEDs and the battery tucked underneath.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;base of light with cover removed&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/fix-bunny-led-cover-removed.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;It turned out to be a 18650 lithium battery.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;base disassembled showing the battery connected&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/fix-bunny-led-battery.webp&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Adam Savage has since released a &lt;a href=&#34;https://www.youtube.com/watch?v=-Y23nfAOiXQ&#34;&gt;video about 18650 batteries&lt;/a&gt; which probably explains why it stopped working.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You&amp;rsquo;ll get a lot of options when searching for 18650 batteries but the tricky part was finding one with the right connector.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;jst connector of the battery&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/fix-bunny-led-jst-connector.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.amazon.com/dp/B0GKGN81L9&#34;&gt;This replacement worked&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/electronics/fix-bunny-led/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>JST connectors</title>
      <link>https://www.brandonpugh.com/til/electronics/jst-connector/</link>
      <pubDate>Sun, 13 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/electronics/jst-connector/</guid>
      <description>&lt;p&gt;Today I learned that the following white connector you commonly see in electronic devices, is called a &lt;a href=&#34;https://en.wikipedia.org/wiki/JST_connector&#34;&gt;&amp;ldquo;JST connector&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;jst connector&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/electronics/jst-connector-front-cropped-min.jpg&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/electronics/jst-connector/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Semantic line breaks (one sentence per line)</title>
      <link>https://www.brandonpugh.com/til/markdown/semantic-line-breaks/</link>
      <pubDate>Tue, 08 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/markdown/semantic-line-breaks/</guid>
      <description>&lt;p&gt;I just discovered &lt;a href=&#34;https://sembr.org/&#34;&gt;Semantic Line Breaks&lt;/a&gt;.
I could never decide on exactly how to do line breaks in markdown so I love that someone came up with a convention that&amp;rsquo;s been thought through.&lt;/p&gt;
&lt;p&gt;This led me to discover this post by Derek Sivers: &lt;a href=&#34;https://sive.rs/1s&#34;&gt;Writing one sentence per line&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s interesting is that while he&amp;rsquo;s recommending the same approach, he suggests that it will improve your writing itself.&lt;/p&gt;
&lt;p&gt;Nicer git diffs is just a side benefit. 🙂&lt;/p&gt;
&lt;p&gt;Definitely going to adopt this now and see how I like it.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/markdown/semantic-line-breaks/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>The &#34;Inverted Pyramid&#34; in journalism</title>
      <link>https://www.brandonpugh.com/til/writing/inverted-pyramid/</link>
      <pubDate>Tue, 01 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/writing/inverted-pyramid/</guid>
      <description>&lt;p&gt;Continue with the writing, Today I learned about the &lt;a href=&#34;https://en.wikipedia.org/wiki/Inverted_pyramid_%28journalism%29&#34;&gt;inverted pyramid&lt;/a&gt; in journalism:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;sketch of the inverted pyramid&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/writing/inverted-pyramid.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a way to structure content so that it &amp;ldquo;begins with the details that readers care about most. As the article progresses, the focus shifts toward details that are relevant only to the most interested readers.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I came across it in this great post about &lt;a href=&#34;https://refactoringenglish.com/chapters/commit-messages/&#34;&gt;How to Write Useful Commit Messages&lt;/a&gt; but is just as applicable to blog posts/reports/docs/emails.&lt;/p&gt;
&lt;p&gt;As a reader this is nice because you can get the info you care about faster and bail at any point.&lt;br&gt;
As an author you reduce the risk that you&amp;rsquo;ll lose people before you&amp;rsquo;ve made your main point.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://mtlynch.io/&#34;&gt;Michael Lynch&lt;/a&gt; has a lot of great &lt;a href=&#34;https://refactoringenglish.com/chapters/&#34;&gt;content on writing&lt;/a&gt; for developers and is working on turning it into a book: &lt;a href=&#34;https://refactoringenglish.com/&#34;&gt;Refactoring English&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/writing/inverted-pyramid/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>On dashes</title>
      <link>https://www.brandonpugh.com/til/writing/dashes/</link>
      <pubDate>Mon, 31 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/writing/dashes/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been working on improving my writing and since it&amp;rsquo;s an important skill in our industry I figured it&amp;rsquo;s also a category of learnings worth sharing.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been experimenting with using em dashes (—) lately but I just learned that it&amp;rsquo;s common to &lt;em&gt;not&lt;/em&gt; put spaces around it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Spacing around an em dash varies. Most newspapers insert a space before and after the dash, and many popular magazines do the same, but most books and journals omit spacing, closing whatever comes before and after the em dash right up next to it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I personally think I&amp;rsquo;ll prefer adding spaces — at least in my own writing — since it looks more distinct from a hyphenated word.
I also saw it mentioned somewhere that some software incorrectly teats it as a hyphenated word when double clicking or press and holding for selection.
This also makes me realized I may have written some word-counting logic incorrectly in the past 😅&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.merriam-webster.com/grammar/em-dash-en-dash-how-to-use&#34;&gt;How to Use Em Dashes (—), En Dashes (–) , and Hyphens (-) | Merriam-Webster&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/writing/dashes/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Run old versions of Angular</title>
      <link>https://www.brandonpugh.com/til/node/old-project-versions/</link>
      <pubDate>Thu, 20 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/node/old-project-versions/</guid>
      <description>&lt;p&gt;Today I learned how to get a very old Angular project running locally.
Even though it was Angular in this case, the steps are likely to be similar for most aging node based projects.&lt;/p&gt;
&lt;p&gt;First I had to go to the &lt;a href=&#34;https://angular.dev/reference/versions&#34;&gt;Version compatibility&lt;/a&gt; page for Angular and find the required version of node.
In my case it was Angular v7 so I needed Node v10.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll want to use a version manager for node.&lt;br&gt;
nvm is the most well known but you have to run it in bash on Windows and I find &lt;a href=&#34;https://volta.sh/&#34;&gt;Volta&lt;/a&gt; much nicer to use.&lt;/p&gt;
&lt;p&gt;I ran &lt;code&gt;volta pin node@10&lt;/code&gt; in the project directory.
This will add a &lt;code&gt;volta&lt;/code&gt; config section to the package.json so that whenever you&amp;rsquo;re in that directory, you&amp;rsquo;ll automatically use the correct version of node and npm.&lt;/p&gt;
&lt;p&gt;Best of all though, it won&amp;rsquo;t affect the default version of node that get&amp;rsquo;s run everywhere else.&lt;/p&gt;
&lt;p&gt;Also make sure you run &lt;code&gt;npm install&lt;/code&gt; &lt;em&gt;after&lt;/em&gt; the above command so that it&amp;rsquo;s the correct version of &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you already tried to run &lt;code&gt;npm i&lt;/code&gt; with a different version of node then you&amp;rsquo;ll probably need to blow away your &lt;code&gt;node_modules&lt;/code&gt; folder and try again (ask me how I know).&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/node/old-project-versions/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>You can style markdown links as code</title>
      <link>https://www.brandonpugh.com/til/markdown/style-links/</link>
      <pubDate>Tue, 18 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/markdown/style-links/</guid>
      <description>&lt;p&gt;I just figured out that you can style a link as inline code in markdown i.e. &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted&#34;&gt;&lt;code&gt;toSorted()&lt;/code&gt;&lt;/a&gt;
It&amp;rsquo;s a bit non-intuitive since, unlike bold or italics, the backticks go &lt;em&gt;inside&lt;/em&gt; the square brackets instead of around the entire link.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;This gives a bold link: &lt;span class=&#34;ge&#34;&gt;**&lt;/span&gt;[&lt;span class=&#34;nt&#34;&gt;EFF&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;https://eff.org&lt;/span&gt;)**.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;This is for italics: &lt;span class=&#34;ge&#34;&gt;*[Markdown Guide](https://www.markdownguide.org)*&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;And this is for code: [&lt;span class=&#34;nt&#34;&gt;`toSorted()`&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;https://www.brandonpugh.com/til/javascript/tosorted/&lt;/span&gt;).
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In my testing this seems supported in most places like github and azure devops. Unfortunately I couldn&amp;rsquo;t find a way get it styled like that in Teams.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/markdown/style-links/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Pressing `%` will also jump to the matching HTML tag</title>
      <link>https://www.brandonpugh.com/til/vim/jump-matching-html-tag/</link>
      <pubDate>Sat, 15 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/jump-matching-html-tag/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve used &lt;code&gt;%&lt;/code&gt; for some time now in vim, but I only just today learned that it not only jumps to a matching bracket or parenthesis, but also a matching &lt;strong&gt;HTML tag&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;Unfortunately this doesn&amp;rsquo;t seem to work with vscode-vim but it does work with vscode-neovim.&lt;/p&gt;
&lt;p&gt;You could also accomplish this by assigning a hotkey to the &amp;ldquo;Go to matching pair&amp;rdquo; Emmet command.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/jump-matching-html-tag/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Profiles in Visual Studio Code</title>
      <link>https://www.brandonpugh.com/til/vscode/profiles/</link>
      <pubDate>Fri, 14 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/profiles/</guid>
      <description>&lt;p&gt;I recently learned that VScode let&amp;rsquo;s you create different &lt;a href=&#34;https://code.visualstudio.com/docs/editor/profiles&#34;&gt;profiles&lt;/a&gt; that let you switch between different sets of settings, keyboard shortcuts, snippets, and most importantly, extensions.&lt;/p&gt;
&lt;p&gt;This is really if, like me, you have various extensions for different types of projects and don&amp;rsquo;t need them all running all the time. For example, I have extensions for C#, react, angular, or markdown projects (apparently I had 86 extensions installed 😱).&lt;/p&gt;
&lt;p&gt;The profile editor is actually pretty nice, letting you copy from an existing profiles for from some builtin templates.&lt;/p&gt;
&lt;p&gt;Unfortunately it doesn&amp;rsquo;t let you easily copy only certain extensions so the easiest way I found to get a list of all my extensions by running &lt;code&gt;code --list-extensions&lt;/code&gt; from the command line and then creating an &lt;code&gt;extensions.json&lt;/code&gt; file in a workspace.
When you open that folder, VScode will see those as &lt;a href=&#34;https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions&#34;&gt;recommended extensions&lt;/a&gt; for that workspace and let you install them all with one click.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Before&lt;/em&gt; I learned of that command however I used &lt;a href=&#34;https://jqlang.org/&#34;&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/a&gt; to get a list of extension IDs from the &lt;code&gt;extensions.json&lt;/code&gt; located in your user directory.
This json file has much more data it in it so &lt;code&gt;jq&lt;/code&gt; makes it much easier to extract the list:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.[].identifier.id&amp;#39;&lt;/span&gt; file.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This approach still might be handy if I want to get a list of extensions only from a specific profile as those are stored in similar json files in &lt;code&gt;/profiles&lt;/code&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/profiles/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Create exclusive accordions with HTML `&lt;details&gt;` element</title>
      <link>https://www.brandonpugh.com/til/html/details-accordion/</link>
      <pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/details-accordion/</guid>
      <description>&lt;p&gt;Today I learned that you can now create an &amp;ldquo;exclusive accordion&amp;rdquo;, meaning only one section of the accordion is open at a time, using just html with the &lt;code&gt;details&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;All you need to do is add a matching &lt;code&gt;name&lt;/code&gt; attribute to each &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; element you want to be considered part of the same &amp;ldquo;group&amp;rdquo;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;details&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;faq&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Section 1&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Section 1 details
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;details&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;details&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;faq&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Section 2&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Section 2 details
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;details&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note, the &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; element has been widely supported since 2020 but support for the &lt;code&gt;name&lt;/code&gt; attribute was only added last year.&lt;/p&gt;
&lt;p&gt;Read more: &lt;a href=&#34;https://developer.mozilla.org/en-US/blog/html-details-exclusive-accordions/&#34;&gt;Exclusive accordions using the HTML details element | MDN Blog&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/details-accordion/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Toggle a CSS class with vanilla javascript</title>
      <link>https://www.brandonpugh.com/til/javascript/classlist/</link>
      <pubDate>Tue, 11 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/classlist/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;code&gt;classList.toggle()&lt;/code&gt; method in JavaScript, which makes it trivial to add or remove a class from an element dynamically:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;button&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;querySelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;button&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;button&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addEventListener&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;click&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;button&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;classList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toggle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;active&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is has been widely supported in browsers since 2015 with the addition of &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Element/classList&#34;&gt;&lt;code&gt;classList&lt;/code&gt;&lt;/a&gt; and makes it a lot easier to manipulate the classes on an element instead of having to manipulate the &lt;code&gt;className&lt;/code&gt; string which is why people used to reach for jQuery for that.&lt;/p&gt;
&lt;p&gt;You can also pass a second argument (&lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;) to explicitly control whether the class should be added or removed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;classList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toggle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;hidden&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// Always adds &amp;#34;hidden&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;classList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toggle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;hidden&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Always removes &amp;#34;hidden&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/classlist/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>toSorted() array method</title>
      <link>https://www.brandonpugh.com/til/javascript/tosorted/</link>
      <pubDate>Thu, 06 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/tosorted/</guid>
      <description>&lt;p&gt;Today I learned that there is a newish javascript array method &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted&#34;&gt;&lt;code&gt;toSorted()&lt;/code&gt;&lt;/a&gt; which is the &amp;ldquo;copying&amp;rdquo; or non-mutating version of &lt;code&gt;sort()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This means you can easily sort an array by getting back a new copy instead of mutating the original:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;months&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mar&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Jan&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Feb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Dec&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;sortedMonths&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;months&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toSorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sortedMonths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// [&amp;#39;Dec&amp;#39;, &amp;#39;Feb&amp;#39;, &amp;#39;Jan&amp;#39;, &amp;#39;Mar&amp;#39;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;months&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// [&amp;#39;Mar&amp;#39;, &amp;#39;Jan&amp;#39;, &amp;#39;Feb&amp;#39;, &amp;#39;Dec&amp;#39;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s pretty cool to see javascript moving more towards immutability.
I mentioned the &lt;a href=&#34;https://www.brandonpugh.com/til/javascript/array-with/&#34;&gt;&lt;code&gt;with()&lt;/code&gt; method before&lt;/a&gt; and now there is also &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed&#34;&gt;&lt;code&gt;toReversed()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSpliced&#34;&gt;&lt;code&gt;toSpliced()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These were added in ES2023 and have been available in browsers since July 2023.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/tosorted/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Split lines in Vim</title>
      <link>https://www.brandonpugh.com/til/vim/split-lines/</link>
      <pubDate>Tue, 04 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/split-lines/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve long wanted a command that was the opposite of &lt;code&gt;J&lt;/code&gt; (join lines), and I finally took the time to see if it&amp;rsquo;s possible.
Turns out there a few solutions.&lt;/p&gt;
&lt;p&gt;The simplest way if you want to split on a whitespace character is to just type &lt;code&gt;r&lt;/code&gt; &lt;code&gt;enter&lt;/code&gt;.
I can&amp;rsquo;t believe I never thought of that before.&lt;/p&gt;
&lt;p&gt;You can also install the &lt;a href=&#34;https://github.com/drzel/vim-split-line&#34;&gt;vim-split-line&lt;/a&gt; plugin, which adds the &lt;code&gt;:SplitLine&lt;/code&gt; command.
This command will split the current line at the cursor position.&lt;/p&gt;
&lt;p&gt;But, as they note in their README, you can also use the following command to split the line at the cursor position:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-vim&#34; data-lang=&#34;vim&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;nnoremap&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;S&lt;/span&gt; :&lt;span class=&#34;nx&#34;&gt;keeppatterns&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;substitute&lt;/span&gt;&lt;span class=&#34;sr&#34;&gt;/\s*\%#\s*/&lt;/span&gt;\&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;/&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;normal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;==&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;CR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/split-lines/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>b is an Alias for Parenthesis in Vim</title>
      <link>https://www.brandonpugh.com/til/vim/text-object-alias/</link>
      <pubDate>Mon, 03 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/text-object-alias/</guid>
      <description>&lt;p&gt;I just discovered that &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; are aliases for the &lt;code&gt;()&lt;/code&gt; and &lt;code&gt;{}&lt;/code&gt; text objects respectively.&lt;/p&gt;
&lt;p&gt;This is a nice little builtin improvement since I frequently find myself selecting or changing withing parenthesis and &lt;code&gt;cib&lt;/code&gt; is nicer to type than &lt;code&gt;ci(&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I only wished I&amp;rsquo;d discovered this years ago!&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/text-object-alias/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Dotnet StringSyntaxAttribute</title>
      <link>https://www.brandonpugh.com/til/csharp/string-syntax-attribute/</link>
      <pubDate>Fri, 21 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/csharp/string-syntax-attribute/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;code&gt;StringSyntaxAttribute&lt;/code&gt; added in .NET 7.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a handy attribute you can add to string properties to specify exactly what format the string should be in.&lt;/p&gt;
&lt;p&gt;This gives you extra IDE assistance like syntax highlighting and intellisense 🔥.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of rider showing regex intellisense&#34; loading=&#34;lazy&#34; src=&#34;https://linkdotnetblog.azureedge.net/blog/20230101_StringSyntax/Preview.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;And you can also use a comment like &lt;code&gt;/*lang=xxx*/&lt;/code&gt; for regular variables.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of comment annotation&#34; loading=&#34;lazy&#34; src=&#34;https://www.alwaysdeveloping.net/dailydrop/2022/03/28-stringsyntaxattribute/3.non-attribute.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Read &lt;a href=&#34;https://steven-giesel.com/blogPost/d2b2fc18-ca4c-4879-b87f-a1d36f435805&#34;&gt;Steve&amp;rsquo;s post&lt;/a&gt; for more detail.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/csharp/string-syntax-attribute/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use the &lt;picture&gt; element for light/dark images in markdown</title>
      <link>https://www.brandonpugh.com/til/html/light-dark-images/</link>
      <pubDate>Wed, 19 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/light-dark-images/</guid>
      <description>&lt;p&gt;Thanks to &lt;a href=&#34;https://jamesg.blog/2025/02/17/images-light-dark-css&#34;&gt;James&amp;rsquo; post&lt;/a&gt;, today I learned that you can use the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; to display different images based on whether or not the set a preference for light or dark mode.&lt;/p&gt;
&lt;p&gt;The key is using the &lt;code&gt;prefers-color-scheme&lt;/code&gt; CSS media query&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;picture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;media&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;(prefers-color-scheme: dark)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;srcset&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      https://user-images.githubusercontent.com/25423296/163456776-7f95b81a-f1ed-45f7-b7ab-8fa810d529fa.png
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;img&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;alt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Shows an illustrated sun in light color mode and a moon with stars in dark color mode.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://user-images.githubusercontent.com/25423296/163456779-a8556205-d0a5-45e2-ac17-42d089e3c3f8.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;picture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since HTML is valid in markdown, you can easily use this technique in a number of places including Github—which apparently has allowed the use of the &lt;code&gt;picture&lt;/code&gt; element &lt;a href=&#34;https://github.blog/changelog/2022-05-19-specify-theme-context-for-images-in-markdown-beta/&#34;&gt;since 2022.&lt;/a&gt;
This is much better than the custom syntax they had before.&lt;/p&gt;
&lt;p&gt;This also aligns with the sentiment Dave expressed that &lt;a href=&#34;https://daverupert.com/2023/05/markdown-images-anti-pattern/&#34;&gt;Markdown images are an anti-pattern&lt;/a&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/light-dark-images/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use jq to get a list of deeply nested values from JSON</title>
      <link>https://www.brandonpugh.com/til/javascript/jq-get-list-nested-json/</link>
      <pubDate>Wed, 05 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/jq-get-list-nested-json/</guid>
      <description>&lt;p&gt;I needed the list of extensions from the &lt;code&gt;extensions.json&lt;/code&gt; that looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;identifier&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;asvetliakov.vscode-neovim&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1.18.22&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I hadn&amp;rsquo;t used &lt;code&gt;jq&lt;/code&gt; before but knew this was exactly what it was made for.&lt;/p&gt;
&lt;p&gt;In this case all I needed was this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.[].identifier.id&amp;#39;&lt;/span&gt; extensions.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also they have a pretty cool &lt;a href=&#34;https://play.jqlang.org/&#34;&gt;Playground&lt;/a&gt; for experimenting or running one-off queries.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/jq-get-list-nested-json/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Github supports alerts in markdown</title>
      <link>https://www.brandonpugh.com/til/github/markdown-alerts/</link>
      <pubDate>Fri, 31 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/github/markdown-alerts/</guid>
      <description>&lt;p&gt;Today I learned that Github &lt;a href=&#34;https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts&#34;&gt;supports alerts&lt;/a&gt; in markdown using the blockquote syntax:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&#34;ge&#34;&gt;[!NOTE]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&#34;ge&#34;&gt;Useful information that users should know, even when skimming content.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is an extension to the standard markdown syntax that I&amp;rsquo;ve seen supported more and more in various markdown tools like Obsidian and vscode (they&amp;rsquo;re also referred to as callouts or admonitions).&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/github/markdown-alerts/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>npmpackage.info</title>
      <link>https://www.brandonpugh.com/til/node/npm-package-info/</link>
      <pubDate>Thu, 30 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/node/npm-package-info/</guid>
      <description>&lt;p&gt;I recently discovered this handy site that aggregates all usual info I tend to look at when deciding whether or not I want to pull in an NPM package as a dependency.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://npmpackage.info/package/react-datepicker?t=overview&#34;&gt;npmpackage.info&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some things I tend to look at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When was the last version published?&lt;/li&gt;
&lt;li&gt;How many sub-dependencies does it have?
&lt;ul&gt;
&lt;li&gt;With the rise in supply chain attacks, newer packages try to minimize these with some advertising zero dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How much will it add to bundle size?
&lt;ul&gt;
&lt;li&gt;I usually check &lt;a href=&#34;https://bundlephobia.com/&#34;&gt;Bundlephobia&lt;/a&gt; and this displays the stats from there along with everything else&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How widely used is it?&lt;/li&gt;
&lt;/ul&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/node/npm-package-info/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>uv package manager</title>
      <link>https://www.brandonpugh.com/til/python/uv-package-manager/</link>
      <pubDate>Mon, 27 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/python/uv-package-manager/</guid>
      <description>&lt;p&gt;I recently came across this post, &lt;a href=&#34;https://valatka.dev/2025/01/12/on-killer-uv-feature.html&#34;&gt;Uv has a killer feature you should know about&lt;/a&gt;, which led me to discover the &lt;a href=&#34;https://github.com/astral-sh/uv&#34;&gt;uv&lt;/a&gt; package and project manager for Python.
This seems to be the new preferred tool for managing python versions/dependencies as it&amp;rsquo;s faster and can replace pyenv, pip, virtualenv, and others.&lt;/p&gt;
&lt;p&gt;It just saved me some headache as I tend to mostly use python for various tools and I tried to install a package the other day with &lt;code&gt;pip install&lt;/code&gt; but it failed with some inscrutable error.
Then I realized the package wouldn&amp;rsquo;t work with python 3.13 which I&amp;rsquo;d been using — and python 3.12 was causing a sub dependency to throw warnings — but 3.11 turned out to be the lucky version which &lt;code&gt;uv&lt;/code&gt; made it easy to setup with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv python install 3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv add tool &amp;lt;package&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Their &lt;a href=&#34;https://docs.astral.sh/uv/#getting-started&#34;&gt;docs&lt;/a&gt; were really helpful and installing it was pretty easy even on windows.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/python/uv-package-manager/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>A single input in a form can submit</title>
      <link>https://www.brandonpugh.com/til/html/single-text-field-submit/</link>
      <pubDate>Tue, 07 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/single-text-field-submit/</guid>
      <description>&lt;p&gt;Today I learned that if you have a single text field in a form then browsers will automatically submit it when you press &lt;code&gt;enter&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Search
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is kinda handy since normally you need to add a submit button to be able to submit a form — but, you should be aware that if you add another field then you &lt;em&gt;do&lt;/em&gt; need to add a submit button for the form to work.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.htmhell.dev/adventcalendar/2024/10/&#34;&gt;This post&lt;/a&gt; goes into more detail.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/single-text-field-submit/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Type check and cast</title>
      <link>https://www.brandonpugh.com/til/csharp/type-check-and-cast/</link>
      <pubDate>Fri, 13 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/csharp/type-check-and-cast/</guid>
      <description>&lt;p&gt;Today I learned that you can use pattern matching in C# to check for a type and cast to it in the same expression.
See &lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching&#34;&gt;the docs&lt;/a&gt; for more details.&lt;/p&gt;
&lt;p&gt;Microsoft even has a &lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0020-ide0038&#34;&gt;lint rule&lt;/a&gt; for it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Fruit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// Noncompliant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fruit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// or x as Fruit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Fruit&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fruit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/csharp/type-check-and-cast/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>setSelectionRange in Safari will focus the input</title>
      <link>https://www.brandonpugh.com/til/html/setselectionrange/</link>
      <pubDate>Sun, 08 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/setselectionrange/</guid>
      <description>&lt;p&gt;Apparently in Safari, &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange&#34;&gt;&lt;code&gt;setSelectionRange()&lt;/code&gt;&lt;/a&gt; will focus the element even when not focused despite MDN stating that &amp;ldquo;The element must be focused for the call to have any effect&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;According to this &lt;a href=&#34;https://bugs.webkit.org/show_bug.cgi?id=224425&#34;&gt;bug&lt;/a&gt;, this is considered intended behavior even though it&amp;rsquo;s inconsistent with MDN and the other browsers.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s worth noting though, during my testing, I noticed that Chrome/Firefox &lt;em&gt;will&lt;/em&gt; update the selection and cursor position you just won&amp;rsquo;t see it unless you programmatically call &lt;code&gt;.focus()&lt;/code&gt; on the element.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/setselectionrange/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Stash changes in the index</title>
      <link>https://www.brandonpugh.com/til/git/stash-index/</link>
      <pubDate>Wed, 27 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/stash-index/</guid>
      <description>&lt;p&gt;I just recently discovered that Git 2.35 added the &lt;code&gt;--staged&lt;/code&gt; option to the &lt;code&gt;git stash&lt;/code&gt; command.
This makes it easy to quickly stash only the changes that you&amp;rsquo;ve staged.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/stash-index/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Vim sets auto marks</title>
      <link>https://www.brandonpugh.com/til/vim/auto-marks/</link>
      <pubDate>Sun, 24 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/auto-marks/</guid>
      <description>&lt;p&gt;Today I learned that Vim has some special marks which it sets automatically:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Command&lt;/th&gt;
          &lt;th&gt;Description&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;`.&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;jump to position where last change occurred in current buffer&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;`&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;jump to position where last exited current buffer&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;`0&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;jump to position in last file edited (when exited Vim)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;`1&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;like &lt;code&gt;`0&lt;/code&gt; but the previous file (also &lt;code&gt;`2&lt;/code&gt; etc)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;&#39;&#39;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;jump back (to line in current buffer where jumped from)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;``&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;jump back (to position in current buffer where jumped from)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;&#39;[&lt;/code&gt; or &lt;code&gt;&#39;]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;jump to beginning/end of previously changed or yanked text&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;&#39;&amp;lt;&lt;/code&gt; or &lt;code&gt;&#39;&amp;gt;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;jump to beginning/end of last visual selection&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The funny thing is VsVim displays these in the gutter by default and I never knew what the symbols meant.
Vscode-vim has an option to display marks in the gutter but only the regular marks and not these.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/auto-marks/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Selectively restoring changes from another branch or commit</title>
      <link>https://www.brandonpugh.com/til/git/patch-uses/</link>
      <pubDate>Thu, 21 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/patch-uses/</guid>
      <description>&lt;p&gt;Today I learned that you can use the &lt;code&gt;--patch&lt;/code&gt; parameter with several git commands.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;--patch&lt;/code&gt; parameter is probably most known for interactively staging changes from the cli, but I&amp;rsquo;ve never really used it because I find &lt;a href=&#34;https://www.brandonpugh.com/til/visual-studio/line-staging/&#34;&gt;GUI clients&lt;/a&gt; are much more convenient for this.&lt;/p&gt;
&lt;p&gt;But apparently you can also use it with restore/checkout to grab specific changes from another branch.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git restore --source&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;branch-name --patch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is something I haven&amp;rsquo;t seen easily done in any git client.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://tekin.co.uk/2024/08/the-many-uses-for-git-patch&#34;&gt;Tekin&amp;rsquo;s post it&lt;/a&gt; for more details and other uses.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/patch-uses/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Personal git ignore per repository</title>
      <link>https://www.brandonpugh.com/til/git/personal-git-ignore/</link>
      <pubDate>Tue, 19 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/personal-git-ignore/</guid>
      <description>&lt;p&gt;Today I learned that git has a &lt;code&gt;$GIT_DIR/info/exclude&lt;/code&gt; file can contain additional patterns of files to ignore but isn&amp;rsquo;t committed to the repository.&lt;/p&gt;
&lt;p&gt;For me this is handy for some tooling configuration files that I use personally but don&amp;rsquo;t want to clutter the main &lt;code&gt;.gitignore&lt;/code&gt; of the repo.&lt;/p&gt;
&lt;p&gt;If there are some files that you want to &lt;em&gt;always&lt;/em&gt; ignore, then you can specify a &lt;strong&gt;global&lt;/strong&gt; ignore file in your git config with &lt;code&gt;core.excludesFile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://git-scm.com/docs/gitignore&#34;&gt;The official docs&lt;/a&gt; have a nice breakdown of when to use which method.&lt;/p&gt;
&lt;h2 id=&#34;dont-you-want-to-be-using-the-same-tools-as-the-rest-of-your-team&#34;&gt;Don&amp;rsquo;t you want to be using the same tools as the rest of your team?&lt;/h2&gt;
&lt;p&gt;Great point!
For me it&amp;rsquo;s usually specific editor config files that I have set in my global git ignore file since I&amp;rsquo;d never want them committed.
For example I use vim for certain things so I have these files ignored in &lt;code&gt;~/.gitignore_global&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Swap files
[._]*.s[a-v][a-z]
[._]*.sw[a-p]

# Session
Session.vim

# Temporary
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~

.vscode
.zed
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I have &lt;code&gt;.vscode&lt;/code&gt; in there as well since I occasionally find myself on teams where no one else uses it&amp;hellip; and &lt;a href=&#34;https://zed.dev/&#34;&gt;Zed&lt;/a&gt; is really new but I&amp;rsquo;ve just been playing around with it.&lt;/p&gt;
&lt;p&gt;For repo specific ignores in &lt;code&gt;$GIT_DIR/info/exclude&lt;/code&gt;, it tends to be tools for managing environments like &lt;a href=&#34;https://volta.sh/&#34;&gt;Volta&lt;/a&gt; for node or &lt;a href=&#34;https://asdf-vm.com/&#34;&gt;asdf&lt;/a&gt; and &lt;a href=&#34;https://mise.jdx.dev/&#34;&gt;mise&lt;/a&gt; for other runtimes.&lt;/p&gt;
&lt;p&gt;Also sometimes I find it useful to run some linting tools for myself when the rest of team hasn&amp;rsquo;t bought into it yet.&lt;/p&gt;
&lt;p&gt;For example, it took over a year with recent team to convince them add eslint to the project but in the mean time it was at least catching things for me in the editor with my own code or while reviewing PRs.&lt;/p&gt;
&lt;p&gt;Likewise, I always have &lt;a href=&#34;https://cspell.org/&#34;&gt;cSpell&lt;/a&gt; running with Vscode to spell check my code so I have the &lt;code&gt;project-words.txt&lt;/code&gt; file ignored.
I don&amp;rsquo;t have these ignored globally since in some repos they do end up getting committed.&lt;/p&gt;
&lt;p&gt;But I totally agree, you want to be cognizant of potential conflicts with the rest of the team depending on the tool.
Configuration for tools like code formatters should definitely be shared with the team. And trying to use something like &lt;code&gt;yarn&lt;/code&gt; when the team is using &lt;code&gt;npm&lt;/code&gt;, is asking for trouble.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/personal-git-ignore/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Raw string literals in C# 11</title>
      <link>https://www.brandonpugh.com/til/csharp/raw-string-literals/</link>
      <pubDate>Mon, 18 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/csharp/raw-string-literals/</guid>
      <description>&lt;p&gt;Today I learned about &lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/raw-string&#34;&gt;raw string literals&lt;/a&gt; introduced in C# 11.&lt;/p&gt;
&lt;p&gt;The big improvement to me is that you don&amp;rsquo;t need to escape double quotes.&lt;/p&gt;
&lt;p&gt;So no more of this noise if you need a json string:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;@&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  &amp;#34;&amp;#34;number&amp;#34;&amp;#34;: 42,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  &amp;#34;&amp;#34;text&amp;#34;&amp;#34;: &amp;#34;&amp;#34;Hello, world&amp;#34;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  &amp;#34;&amp;#34;nested&amp;#34;&amp;#34;: { &amp;#34;&amp;#34;flag&amp;#34;&amp;#34;: true }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can now write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;s&#34;&gt;&amp;#34;number&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;42&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;s&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Hello, world&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;s&#34;&gt;&amp;#34;nested&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;flag&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The other nice feature is that an extraneous indentation will stripped out based on the location of the closing &lt;code&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/code&gt;. 🔥&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.stevefenton.co.uk/blog/2022/02/raw-string-literals-in-c/&#34;&gt;This post&lt;/a&gt; goes into it deeper.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/csharp/raw-string-literals/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>SRI integrity hash algorithms</title>
      <link>https://www.brandonpugh.com/til/html/sri-hash-algorithm/</link>
      <pubDate>Tue, 12 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/sri-hash-algorithm/</guid>
      <description>&lt;p&gt;Today I learned that you can actually specify different hash algorithms for &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity&#34;&gt;Subresource Integrity&lt;/a&gt; (SRI) hashes.&lt;/p&gt;
&lt;p&gt;If you aren&amp;rsquo;t familiar with SRI, &lt;a href=&#34;https://frontendmasters.com/blog/script-integrity/&#34;&gt;this post&lt;/a&gt; does a good job explaining why it&amp;rsquo;s useful and how it would have mitigated the recent &lt;a href=&#34;https://www.securityweek.com/polyfill-supply-chain-attack-hits-over-100k-websites/&#34;&gt;pollyfill.io incident&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I needed to add the hashes to some scripts from a third party CDN that didn&amp;rsquo;t provide them and I came across this handy &lt;a href=&#34;https://www.srihash.org/&#34;&gt;generator&lt;/a&gt; which let&amp;rsquo;s you choose which algorithm to use and defaults to SHA-384 and &lt;a href=&#34;https://report-uri.com/home/sri_hash&#34;&gt;report-uri&lt;/a&gt; has a generator that just includes &lt;em&gt;all 3 different hashes&lt;/em&gt; in the &lt;code&gt;integrity&lt;/code&gt; value.&lt;/p&gt;
&lt;p&gt;So which one to use?&lt;/p&gt;
&lt;p&gt;Apparently you can specify different hashes but there isn&amp;rsquo;t much value in doing so at the moment since all modern browsers support all of the available algorithms so you should just pick &lt;strong&gt;&lt;code&gt;SHA512&lt;/code&gt;&lt;/strong&gt;.
In the future however, newer algorithms might be implemented which you could add while maintaining backwards compatibility.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/sri-hash-algorithm/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use `URLSearchParams()` to build a query string</title>
      <link>https://www.brandonpugh.com/til/javascript/urlsearchparams-query-string/</link>
      <pubDate>Thu, 07 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/urlsearchparams-query-string/</guid>
      <description>&lt;p&gt;Today I learned that javascript has a handy built-in function called &lt;code&gt;URLSearchParams()&lt;/code&gt; that you can use to build a url query string from an object.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;petfinderData&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;12345&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;shelterID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;abc00&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;animals&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;dogs&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cats&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;URLSearchParams&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;petfinderData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// returns &amp;#34;key=12345&amp;amp;shelterID=abc00&amp;amp;count=20&amp;amp;animals=dogs%2Ccats&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;queryString&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Read more: &lt;a href=&#34;https://gomakethings.com/how-to-build-a-query-string-from-an-object-of-data-with-vanilla-js/&#34;&gt;https://gomakethings.com/how-to-build-a-query-string-from-an-object-of-data-with-vanilla-js/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll want to be careful with complex object list arrays since it serializes to a form like &lt;code&gt;animals=dogs,cats&lt;/code&gt;, which not be the format the server expects.&lt;/p&gt;
&lt;p&gt;Asp.net model-binding for instance, by default expects a format like &lt;code&gt;animals=dogs&amp;amp;animals=cats&lt;/code&gt; (and some other &lt;a href=&#34;https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-8.0#collections&#34;&gt;variations&lt;/a&gt;).&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/urlsearchparams-query-string/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Edit commit message with git reword</title>
      <link>https://www.brandonpugh.com/til/git/edit-commit-message-with-reword/</link>
      <pubDate>Sat, 02 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/edit-commit-message-with-reword/</guid>
      <description>&lt;p&gt;I discovered that a &lt;a href=&#34;https://git-scm.com/docs/git-commit?ref=blog.gitbutler.com#Documentation/git-commit.txt---fixupamendrewordltcommitgt&#34;&gt;&lt;code&gt;reword&lt;/code&gt;&lt;/a&gt; option was added to &lt;code&gt;--fixup&lt;/code&gt; back in &lt;a href=&#34;https://devclass.com/2021/06/07/got-typos-git-2-32-lands-finally-offers-way-to-reword-commits/&#34;&gt;git 2.32&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The basic command looks like &lt;code&gt;git commit --fixup=reword:&amp;lt;commit&amp;gt;&lt;/code&gt; and you can use it like you would the other &lt;a href=&#34;https://thoughtbot.com/blog/autosquashing-git-commits&#34;&gt;autosquash&lt;/a&gt; commands.&lt;/p&gt;
&lt;p&gt;I recommend creating an alias for it though.
Thanks to &lt;a href=&#34;https://jordanelver.co.uk/blog/2020/06/04/fixing-commits-with-git-commit-fixup-and-git-rebase-autosquash/&#34;&gt;this post&lt;/a&gt;, I&amp;rsquo;ve had a &lt;code&gt;fixup&lt;/code&gt; alias that uses &lt;a href=&#34;https://github.com/junegunn/fzf&#34;&gt;&lt;code&gt;fzf&lt;/code&gt;&lt;/a&gt; to select form recent commits so I created a similar one for reword:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;alias&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nv&#34;&gt;reword&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;!git log -n 50 --pretty=format:&amp;#39;%h %s&amp;#39; --no-merges | fzf | cut -c -7 | xargs -o -I{} git commit --fixup=reword:{}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note, if you&amp;rsquo;re on Windows, you can install &lt;code&gt;fzf&lt;/code&gt; via &lt;a href=&#34;https://chocolatey.org/packages/fzf&#34;&gt;Chocolatey&lt;/a&gt;.
And you might also be interested in &lt;a href=&#34;https://github.com/kelleyma49/PSFzf&#34;&gt;PSFzf&lt;/a&gt; which a Powershell module that wraps &lt;code&gt;fzf&lt;/code&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/edit-commit-message-with-reword/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>View ModelState errors while debugging</title>
      <link>https://www.brandonpugh.com/til/aspnet/view-modelstate-errors/</link>
      <pubDate>Mon, 28 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/aspnet/view-modelstate-errors/</guid>
      <description>&lt;p&gt;Today I learned how you can view the Modelstate errors while debugging a controller in Asp.Net:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;ModelState&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Where&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Errors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Count&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Select&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Just paste that in the watch window.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve tried debugging to find what field is causing the Modelstate to be invalid, you&amp;rsquo;ll know how tedious it is to dig through but thanks to &lt;a href=&#34;https://windowshell.wordpress.com/2016/06/11/realtime-mvc-modelstate-errors-during-debugging/&#34;&gt;this post&lt;/a&gt; for this handy tip!&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/aspnet/view-modelstate-errors/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>View transitions API</title>
      <link>https://www.brandonpugh.com/til/css/view-transition/</link>
      <pubDate>Tue, 22 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/view-transition/</guid>
      <description>&lt;p&gt;Today I learned about the new &lt;a href=&#34;https://developer.chrome.com/docs/web-platform/view-transitions&#34;&gt;view transitions API&lt;/a&gt; and I was pretty impressed with how much of the heavy lifting the browser will now do for you to animate between states.&lt;/p&gt;
&lt;p&gt;Adam Argyle has a &lt;a href=&#34;https://www.youtube.com/watch?v=is1C2RDV4LI&#34;&gt;fun talk&lt;/a&gt; where he shows what you can do with this new API.&lt;/p&gt;
&lt;p&gt;I only had to add a couple of lines of javascript to animate reordering a list of items that would have required a more complicated technique like &lt;a href=&#34;https://aerotwist.com/blog/flip-your-animations/&#34;&gt;FLIP (first last invert play)&lt;/a&gt; in the past.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/view-transition/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Don&#39;t put an error boundary in the root of a react component</title>
      <link>https://www.brandonpugh.com/til/react/error-boundary-root/</link>
      <pubDate>Tue, 15 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/react/error-boundary-root/</guid>
      <description>&lt;p&gt;You probably don&amp;rsquo;t want to put a React error boundary at the root of a component (meaning, wrapping the component&amp;rsquo;s own render output).&lt;/p&gt;
&lt;p&gt;This is because error boundaries only catch errors in their child component tree.
They won&amp;rsquo;t catch errors that occur within the error boundary component itself, including errors in its own render method or lifecycle methods.&lt;/p&gt;
&lt;p&gt;To use an error boundary effectively, you need to wrap the component you want to protect with the error boundary from the parent.&lt;/p&gt;
&lt;p&gt;For example, you might think to put the error boundary inside a list item that gets rendered in a list:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-jsx&#34; data-lang=&#34;jsx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ChatMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// If parsing JSON fails, the error boundary inside won&amp;#39;t catch it
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;parsedData&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;JSON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ErrorBoundary&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;fallback&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Failed&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;display&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;}&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parsedData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;author&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parsedData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ErrorBoundary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ChatList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;messages&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;chat-container&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ChatMessage&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;))}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The correct approach would be putting the error boundary in the parent component:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-jsx&#34; data-lang=&#34;jsx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ChatMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;parsedData&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;JSON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parsedData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;author&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parsedData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ChatList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;messages&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Correct approach with error boundary wrapping from parent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;chat-container&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ErrorBoundary&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;fallback&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Failed&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;display&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;}&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ChatMessage&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ErrorBoundary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;))}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/react/error-boundary-root/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Console.trace()</title>
      <link>https://www.brandonpugh.com/til/javascript/console-trace/</link>
      <pubDate>Thu, 10 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/console-trace/</guid>
      <description>&lt;p&gt;Today I learned about &lt;code&gt;console.trace()&lt;/code&gt; when I needed to find out where a global function was being overridden:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;defineProperty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;setErrorMessage&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Global variable set:&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This little snippet outputs a stack trace anywhere code was trying to define this global function and let me right to the culprit.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/console/trace_static&#34;&gt;See more about .trace()&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/console-trace/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>History API state</title>
      <link>https://www.brandonpugh.com/til/html/history-state/</link>
      <pubDate>Mon, 07 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/history-state/</guid>
      <description>&lt;p&gt;Today I learned that you can actually store state in the browser history via the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/History&#34;&gt;history API&lt;/a&gt; (note this is not the query string).&lt;/p&gt;
&lt;p&gt;I came across in &lt;a href=&#34;https://darekkay.com/blog/preserve-form-values/&#34;&gt;this post&lt;/a&gt; that uses it as a clever method for temporarily storing form data.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/history-state/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>New hotkey for commenting code</title>
      <link>https://www.brandonpugh.com/til/visual-studio/toggle-commented-code-hotkey/</link>
      <pubDate>Thu, 03 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/visual-studio/toggle-commented-code-hotkey/</guid>
      <description>&lt;p&gt;Today I learned that in a recent version of visual studio they added the keyboard shortcut &lt;code&gt;ctrl+/&lt;/code&gt; to toggle code comments so it works just like in vscode instead of the default of two different cumbersome hotkeys to comment/uncomment.&lt;/p&gt;
&lt;p&gt;This also led me to discover that Visual Studio comes with a builtin &lt;a href=&#34;https://stackoverflow.com/a/62414810/1715138&#34;&gt;keyboard mapping scheme for VSCode&lt;/a&gt; hotkeys which has more modern defaults.
For instance, it changes &lt;code&gt;ctrl+p&lt;/code&gt; to open the fuzzy file finder instead of the print dialog&amp;hellip; I don&amp;rsquo;t know that I&amp;rsquo;ve ever wanted to print a source code file&amp;hellip;&lt;br&gt;
except one time long ago when I wanted to convince a higher-up the need to refactor a sql query so I taped together the 10+ page printout 😅.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/visual-studio/toggle-commented-code-hotkey/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Chain-of-Thought Prompting</title>
      <link>https://www.brandonpugh.com/til/ai/train-of-thought/</link>
      <pubDate>Fri, 20 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/ai/train-of-thought/</guid>
      <description>&lt;p&gt;Today I learned about &lt;a href=&#34;https://www.promptingguide.ai/techniques/cot&#34;&gt;Chain-of-Thought Prompting&lt;/a&gt; which is a technique to get potentially better results from an LLM where you craft your prompt with an example of the chain of thought or steps in reasoning to solve a complex problem.&lt;/p&gt;
&lt;p&gt;This gives a good explanation:
&lt;a href=&#34;https://www.promptingguide.ai/techniques/cot&#34;&gt;https://www.promptingguide.ai/techniques/cot&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/ai/train-of-thought/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>HTTP files</title>
      <link>https://www.brandonpugh.com/til/vscode/http-files/</link>
      <pubDate>Fri, 13 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/http-files/</guid>
      <description>&lt;p&gt;Today I learned about &lt;code&gt;.http&lt;/code&gt; files that you can use to make/test requests to any api endpoint from within most IDEs/editors.&lt;/p&gt;
&lt;p&gt;This started with the &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=humao.rest-client&#34;&gt;Rest client&lt;/a&gt; vscode extension and then &lt;a href=&#34;https://learn.microsoft.com/en-us/aspnet/core/test/http-files?view=aspnetcore-8.0&#34;&gt;Visual Studio 2022&lt;/a&gt; added support somewhat recently.&lt;/p&gt;
&lt;p&gt;It kinda acts like an alternative to something like Postman but without leaving your editor, but for me the nice thing is it can act like a runnable form of documentation for your api that you can commit alongside your code.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/http-files/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>ASP.NET max upload file size</title>
      <link>https://www.brandonpugh.com/til/aspnet/max-upload-file-size/</link>
      <pubDate>Fri, 30 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/aspnet/max-upload-file-size/</guid>
      <description>&lt;p&gt;Today I learned there are &lt;em&gt;two&lt;/em&gt; configuration values that determine how large of a file can be uploaded.
&lt;code&gt;maxRequestLength&lt;/code&gt; is specified in &lt;strong&gt;Kilobytes&lt;/strong&gt; and it&amp;rsquo;s used by the ASP.NET framework.
If the file is larger than this value then the application will throw &amp;ldquo;content length exceed&amp;rdquo; exception so it just comes back as a 500 which isn&amp;rsquo;t that helpful.
The default is about 4mb.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;maxAllowedContentLength&lt;/code&gt; is used by IIS and is specified in &lt;strong&gt;bytes&lt;/strong&gt; not kilobytes and if the file is larger then it will return 413 error status which we can handle appropriately.
The default is about 28mb.&lt;/p&gt;
&lt;p&gt;Both of these values need to set to larger than the file size we want to allow but in our case we needed the &lt;code&gt;maxAllowedContentLength&lt;/code&gt; to be the smaller value so that an upload that&amp;rsquo;s too large will always get rejected by IIS first so we can display a useful error message to the user.&lt;/p&gt;
&lt;p&gt;The issue we ran into was if the file was more than 4mb but less than 28mb, it was reject by aspnet and throwing a 500 which in production comes back as a 302 redirect to the error page which we weren&amp;rsquo;t handling so it would look like the upload was just hanging.&lt;/p&gt;
&lt;p&gt;If the file was larger than 28mb then it would get rejected by IIS and return a 413 which we &lt;em&gt;were&lt;/em&gt; handling so we would display the correct &amp;ldquo;File is too large&amp;rdquo; error message.&lt;/p&gt;
&lt;p&gt;There are even more ways to limit upload size you read about in Kahlid&amp;rsquo;s post: &lt;a href=&#34;https://khalidabuhakmeh.com/increase-file-upload-limit-for-aspdotnet&#34;&gt;increase file upload limit&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/aspnet/max-upload-file-size/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>UUID v7</title>
      <link>https://www.brandonpugh.com/til/javascript/uuid-v7/</link>
      <pubDate>Wed, 21 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/uuid-v7/</guid>
      <description>&lt;p&gt;Today I learned that there are 8 versions of UUID!&lt;/p&gt;
&lt;p&gt;I was vaguely aware that there were some older versions that aren&amp;rsquo;t recommended but just this past May the RFC was approved that added versions 6, 7, and 8.&lt;/p&gt;
&lt;p&gt;Basically, v4 is a good default if you just need a good unguessable random ID. For javascript, this is now built into browsers via &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID&#34;&gt;&lt;code&gt;crypto.randomUUID()&lt;/code&gt;&lt;/a&gt; — or in dotnet with &lt;code&gt;Guid.NewGuid()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But &lt;a href=&#34;https://uuid7.com/&#34;&gt;v7&lt;/a&gt; is an exciting new option because it&amp;rsquo;s time-based so the UUIDs are sortable based on when it was created and you can even &lt;a href=&#34;https://park.is/blog_posts/20240803_extracting_timestamp_from_uuid_v7/&#34;&gt;extract the timestamp&lt;/a&gt; if you want.
This also apparently makes it &lt;a href=&#34;https://itnext.io/why-uuid7-is-better-than-uuid4-as-clustered-index-edb02bf70056&#34;&gt;better as a database key&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/uuidjs/uuid&#34;&gt;uuid&lt;/a&gt; npm package just added support for v7 if you need it in javascript.
For C#, v7 support is &lt;a href=&#34;https://steven-giesel.com/blogPost/ea42a518-4d8b-4e08-8f73-e542bdd3b983&#34;&gt;coming in dotnet 9&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is a nice &lt;a href=&#34;https://www.ntietz.com/blog/til-uses-for-the-different-uuid-versions/&#34;&gt;overview of the different versions&lt;/a&gt; if you want to read more.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/uuid-v7/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Quickly change the end of a line</title>
      <link>https://www.brandonpugh.com/til/vscode/line-ending-regex/</link>
      <pubDate>Tue, 20 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/line-ending-regex/</guid>
      <description>&lt;p&gt;This is a simple thing but I just discovered that with a simple regex and find/replace in most editors, you can quickly add text to the end of every line.&lt;/p&gt;
&lt;p&gt;For instance, if you want to add a &lt;code&gt;,&lt;/code&gt; to every line, all you need is &lt;code&gt;$&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of vscode find/replace UI&#34; loading=&#34;lazy&#34; src=&#34;line-ending-regex.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Or if you want to replace whatever the last character then you can use &lt;code&gt;.$&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;Of course, I use &lt;a href=&#34;https://github.com/vscode-neovim/vscode-neovim&#34;&gt;vscode-neovim&lt;/a&gt; so I just type &lt;code&gt;:%s/$/,/&lt;/code&gt; 😁&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/line-ending-regex/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Abort controller</title>
      <link>https://www.brandonpugh.com/til/javascript/abort-fetch/</link>
      <pubDate>Wed, 24 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/abort-fetch/</guid>
      <description>&lt;p&gt;Today I learned that you can cancel fetch requests using the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/AbortController&#34;&gt;AbortController&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This used to be a major shortcomming of fetch but apparently it&amp;rsquo;s been part of the web platform since 2019.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://kettanaito.com/blog/dont-sleep-on-abort-controller&#34;&gt;This post&lt;/a&gt; also explains some additional use cases for the &lt;code&gt;AbortController&lt;/code&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/abort-fetch/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Drag and drop upload</title>
      <link>https://www.brandonpugh.com/til/html/drag-drop-upload/</link>
      <pubDate>Wed, 24 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/drag-drop-upload/</guid>
      <description>&lt;p&gt;Today I learned that creating a nice drag-and-drop file component using vanilla javascript and the built web APIs is actually fairly easy.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.smashingmagazine.com/2018/01/drag-drop-file-uploader-vanilla-js/&#34;&gt;Smashing Magazine&lt;/a&gt; has an easy-to-follow example.&lt;/p&gt;
&lt;p&gt;The gist of it is that the browser gives you &lt;code&gt;&#39;dragenter&#39;, &#39;dragover&#39;, &#39;dragleave&#39;&lt;/code&gt; events that you can use to style your &amp;ldquo;dropzone&amp;rdquo; however you want and the &lt;code&gt;drop&lt;/code&gt; event allows you to handle the files themselves:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;dropArea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addEventListener&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;drop&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;handleDrop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;handleDrop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;dt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dataTransfer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;files&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// implement with your preferred upload method
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;uploadFiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;dragevent&lt;/code&gt; and &lt;code&gt;dataTransfer&lt;/code&gt; interface have been supported in modern browsers for some time so they are pretty safe to use.&lt;/p&gt;
&lt;p&gt;Alternatively, if you don&amp;rsquo;t care about styling a fancy drop area, the standard HTML &lt;code&gt;&amp;lt;input type=&amp;quot;file&amp;quot;&amp;gt;&lt;/code&gt; element supports dragging a file onto it.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/drag-drop-upload/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Input modes</title>
      <link>https://www.brandonpugh.com/til/html/input-modes/</link>
      <pubDate>Wed, 17 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/input-modes/</guid>
      <description>&lt;p&gt;Today I learned that iOS changed the way it handles the &lt;code&gt;inputmode=&amp;quot;numeric&amp;quot;&lt;/code&gt; attribute on HTML input elements.&lt;/p&gt;
&lt;p&gt;It used to display the full number keyboard as shown here:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of IOS numeric keyboard from version 12.2 which is just the regular keyboard but starting on the number and symbols view&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/html/ios-original-keyboard.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;I couldn&amp;rsquo;t find it documented anywhere but, after testing various versions on BrowserStack, I found that starting with iOS 14 the &lt;code&gt;numeric&lt;/code&gt; keyboard is the same as &lt;code&gt;decimal&lt;/code&gt; but without the decimal key:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of IOS keyboard showing only the 10 large number keys&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/html/ios-numeric-keyboard.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;This is overall an improvement in usability I think except if you need to allow the user to enter negative numbers. So something to be aware of since I couldn&amp;rsquo;t find any way to type the &lt;code&gt;-&lt;/code&gt; with that attribute set.&lt;/p&gt;
&lt;p&gt;Unfortunately, all the sites I found that discuss inputmodes, show the old version like &lt;a href=&#34;https://css-tricks.com/better-form-inputs-for-better-mobile-user-experiences/&#34;&gt;this post&lt;/a&gt; but it&amp;rsquo;s still a good resource and I recommend setting an inputmode where it makes to make it easier to type certain values on mobile devices.&lt;/p&gt;
&lt;p&gt;Also, I like how Android handles it better:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of android numeric keyboards which in addition to the large number keys also has comma, dot, dash, and space keys&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/html/android-numeric-keyboard.png&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/input-modes/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>:has selector</title>
      <link>https://www.brandonpugh.com/til/css/has-selector/</link>
      <pubDate>Fri, 12 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/has-selector/</guid>
      <description>&lt;p&gt;Today I learned about the new &lt;code&gt;:has()&lt;/code&gt; selector in CSS.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s also referred to as the &amp;ldquo;parent&amp;rdquo; selector and that&amp;rsquo;s probably the most straightforward use case but &lt;a href=&#34;https://bejamas.io/blog/learn-css-has-selector-by-examples-top-use-cases/&#34;&gt;this post&lt;/a&gt; shows several cool use cases.&lt;/p&gt;
&lt;p&gt;I used it today when I needed to apply a style to a shared root element but only on a specific page, but all of the styles are bundled into a single CSS file that&amp;rsquo;s loaded on every page:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;app-root&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;signin-root&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/has-selector/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use media queries in javascript with the `matchMedia()` method</title>
      <link>https://www.brandonpugh.com/til/javascript/match-media/</link>
      <pubDate>Wed, 10 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/match-media/</guid>
      <description>&lt;p&gt;Today I learned that the &lt;code&gt;matchMedia()&lt;/code&gt; javascript method lets you match against media queries and respond accordingly with javascript.&lt;/p&gt;
&lt;p&gt;That could look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;mediaQuery&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;matchMedia&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;(min-width: 768px)&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Check if the media query is true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mediaQuery&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// Then trigger an alert
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Media Query Matched!&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can also add an event listener to the &lt;code&gt;mediaQuery&lt;/code&gt; which you&amp;rsquo;ll want to do to respond to the user changing the size of the window — see &lt;a href=&#34;https://css-tricks.com/working-with-javascript-media-queries/&#34;&gt;this post&lt;/a&gt; for details on how to do that.&lt;/p&gt;
&lt;p&gt;Ideally, I try to keep media queries in CSS but this can come in handy for example if you want to change the way a tooltip behaves on smaller screens.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/match-media/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Numeric separators</title>
      <link>https://www.brandonpugh.com/til/javascript/numeric-separators/</link>
      <pubDate>Tue, 02 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/numeric-separators/</guid>
      <description>&lt;p&gt;Today I learned about &lt;a href=&#34;https://v8.dev/features/numeric-separators&#34;&gt;numeric separators&lt;/a&gt; in javascript.
They are a small bit of syntactic sugar to make large numeric literals easier to read by letting you insert underscores anywhere in the number.&lt;/p&gt;
&lt;p&gt;For example, if you need to specify 10mb in byes, instead of &lt;code&gt;10485760&lt;/code&gt;, you can write it as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;maxUploadSize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10_485_760&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;They were added in ECMAScript 2021 and in C# 7.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/numeric-separators/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Clear site data</title>
      <link>https://www.brandonpugh.com/til/devtools/clear-site-data/</link>
      <pubDate>Thu, 27 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/clear-site-data/</guid>
      <description>&lt;p&gt;protip: if you need to clear out some saved data (like cookies) for a particular site, Chrome dev tools has a handy &amp;ldquo;Clear site data&amp;rdquo; function.&lt;/p&gt;
&lt;p&gt;You can get to it from the &amp;ldquo;Application&amp;rdquo; tab:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;alt text&#34; loading=&#34;lazy&#34; src=&#34;image-1.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;or from the command palette which you can invoke with &lt;code&gt;ctrl+shift+p&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;alt text&#34; loading=&#34;lazy&#34; src=&#34;image-2.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;To me this is much more convenient than trying to go through the normal user settings for clearing&lt;/p&gt;
&lt;p&gt;There is also chrome://settings/content/siteDetails?site=https%3A%2F%2Flocalhost&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/clear-site-data/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>bash vs sh in git hooks on windows</title>
      <link>https://www.brandonpugh.com/til/git/bash-hooks/</link>
      <pubDate>Wed, 19 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/bash-hooks/</guid>
      <description>&lt;p&gt;Today I learned that &lt;code&gt;sh&lt;/code&gt; is not the same thing as &lt;code&gt;bash&lt;/code&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/bash-hooks/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Chrome devtools ignores form resubmission</title>
      <link>https://www.brandonpugh.com/til/devtools/ignore-form-resubmission/</link>
      <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/ignore-form-resubmission/</guid>
      <description>&lt;p&gt;Today I learned that if you have the chrome devtools open, then Chrome will suppress the confirm form resubmission dialog:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of chrome resubmission dialog&#34; loading=&#34;lazy&#34; src=&#34;ignore-form-resubmission.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;This threw me off for a minute because I couldn&amp;rsquo;t figure out how the page was maintaining the state when I would refresh after a post.&lt;/p&gt;
&lt;p&gt;I couldn&amp;rsquo;t find it documented anywhere but it&amp;rsquo;s a nice convenience during development though it could be confusing if you&amp;rsquo;re unaware of it.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/ignore-form-resubmission/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Cherry pick a range of commits</title>
      <link>https://www.brandonpugh.com/til/git/cherry-pick-range/</link>
      <pubDate>Tue, 04 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/cherry-pick-range/</guid>
      <description>&lt;p&gt;I just recently learned that you can actually cherry pick a range of commits instead of just a single commit:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git cherry-pick c1..c3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above is using the two-dot &lt;a href=&#34;https://darekkay.com/blog/git-commit-ranges/&#34;&gt;range notation&lt;/a&gt; (&lt;code&gt;..&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;I was a bit surprised by this because I thought that this was the purpose of &lt;code&gt;rebase --onto&lt;/code&gt; — to take a series of commits and apply them one at a time on top of some other commit.&lt;/p&gt;
&lt;p&gt;Turns out that they both essentially do the same thing (for each commit they call &lt;code&gt;merge-base&lt;/code&gt; under the hood and apply a &lt;a href=&#34;https://jvns.ca/blog/2023/11/10/how-cherry-pick-and-revert-work/&#34;&gt;3-way merge&lt;/a&gt; though you can also think of rebase as a series of cherry picks) but one can be more convenient than the other depending on what you&amp;rsquo;re doing or how you prefer to think of the operation.&lt;/p&gt;
&lt;p&gt;Cherry-pick is more convenient if you want to take a series of commits from some &lt;em&gt;other&lt;/em&gt; branch and apply them onto the &lt;em&gt;current&lt;/em&gt; branch.&lt;/p&gt;
&lt;p&gt;Rebase is more convenient if you want to take the &lt;em&gt;current&lt;/em&gt; branch and apply it on top of some &lt;em&gt;other&lt;/em&gt; branch.
And with the &lt;code&gt;--onto&lt;/code&gt; parameter you can change the base or &amp;ldquo;parent branch&amp;rdquo;.
This is a bit harder to wrap your head around but extremely powerful.&lt;/p&gt;
&lt;p&gt;For example given the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        H---I---J topicB
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        /
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              E---F---G  topicA
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              /
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;A---B---C---D  main
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;```txt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If you run `git rebase --onto master topicA topicB` then you end up with:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;```txt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              H&amp;#39;--I&amp;#39;--J&amp;#39;  topicB
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            /
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            | E---F---G  topicA
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            |/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;A---B---C---D  main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which is handy if you started working on &lt;code&gt;topicB&lt;/code&gt; and thought you were branched off of &lt;code&gt;main&lt;/code&gt; instead of &lt;code&gt;topicA&lt;/code&gt; or if &lt;code&gt;topicA&lt;/code&gt; got merged or squashed from under you.
This &lt;a href=&#34;https://stackoverflow.com/a/29916361/1715138&#34;&gt;SO answer&lt;/a&gt; does a great job explaining &lt;code&gt;--onto&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Just remember: &lt;code&gt;git rebase --onto &amp;lt;newparent&amp;gt; &amp;lt;oldparent&amp;gt; &amp;lt;until&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To accomplish the same with cherry-pick would require something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git checkout main
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git branch -b temp &lt;span class=&#34;c1&#34;&gt;# create a new temp branch and switch to it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git cherry-pick topicA..topicB
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git checkout topicB
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git reset --hard temp &lt;span class=&#34;c1&#34;&gt;# topicB is now updated to match temp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git branch --delete temp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/cherry-pick-range/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Nullish Coalescing Operator</title>
      <link>https://www.brandonpugh.com/til/javascript/nullish-coalescing-operator/</link>
      <pubDate>Mon, 03 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/nullish-coalescing-operator/</guid>
      <description>&lt;p&gt;Today I learned that javascript gained a &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing&#34;&gt;nullish coalescing operator&lt;/a&gt; (&lt;code&gt;??&lt;/code&gt;) in ECMAScript 2020.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;potentialEmpty&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;??&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fallbackValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It return the right operand if the left operand is null or undefined so for me this is a convenient alternative to using the OR (&lt;code&gt;||&lt;/code&gt;) operator if I don&amp;rsquo;t want the fallbackValue on falsy values like &lt;code&gt;0&lt;/code&gt; or an empty string.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/nullish-coalescing-operator/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>PC Manager is Microsoft&#39;s cleanup tool</title>
      <link>https://www.brandonpugh.com/til/windows/pc-manager/</link>
      <pubDate>Sun, 02 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/windows/pc-manager/</guid>
      <description>&lt;p&gt;I used to have tools like CCleaner and Revo uninstaller installed on my windows machines but I recently learned that Microsoft now has their utility called &lt;a href=&#34;https://pcmanager.microsoft.com/en-us&#34;&gt;PC Manager&lt;/a&gt; that does things like free up some disk space and disable startup apps.&lt;/p&gt;
&lt;p&gt;Though &lt;a href=&#34;https://www.makeuseof.com/tag/stop-using-ccleaner-windows/&#34;&gt;as this article&lt;/a&gt; points out, you can accomplish a lot of similar tasks without a dedicated tool, so it&amp;rsquo;s more for if you find it convenient.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/windows/pc-manager/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>ISO-8601 Duration Format</title>
      <link>https://www.brandonpugh.com/til/standards/iso-duration/</link>
      <pubDate>Fri, 31 May 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/standards/iso-duration/</guid>
      <description>&lt;p&gt;I learned about the ISO-8601 duration format today.
It&amp;rsquo;s a way to represent a duration of time in a standard format.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;P3Y6M4DT12H30M5S&lt;/code&gt; represents a duration of 3 years, 6 months, 4 days, 12 hours, 30 minutes, and 5 seconds.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.digi.com/resources/documentation/digidocs/90001488-13/reference/r_iso_8601_duration_format.htm&#34;&gt;https://www.digi.com/resources/documentation/digidocs/90001488-13/reference/r_iso_8601_duration_format.htm&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/standards/iso-duration/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>View the conflicts resolved in a merge commit</title>
      <link>https://www.brandonpugh.com/til/git/view-merge-conflicts/</link>
      <pubDate>Wed, 29 May 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/view-merge-conflicts/</guid>
      <description>&lt;p&gt;Today I learned that &lt;a href=&#34;https://github.blog/2022-04-18-highlights-from-git-2-36/#review-merge-conflict-resolution-with-remerge-diff&#34;&gt;in Git 2.36&lt;/a&gt;, the &lt;code&gt;--remerge-diff&lt;/code&gt; option was added to &lt;code&gt;git show&lt;/code&gt;.
This effectively lets you view any merge conflicts that occurred during a merge commit and how they were resolved.&lt;/p&gt;
&lt;p&gt;So for instance, &lt;code&gt;git show --remerge-diff &amp;lt;commit-message-id&amp;gt;&lt;/code&gt; would show something like:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;terminal screenshot of git show output&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/git/view-merge-conflicts.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Under the hood, it recreates the merge with the conflicts and diffs it with the merge commit so the conflict markers are shown in red since the merge commit removes the conflict markers during resolution.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/view-merge-conflicts/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>The viewport scroll bar problem</title>
      <link>https://www.brandonpugh.com/til/css/viewport-scrollbar-problem/</link>
      <pubDate>Tue, 28 May 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/viewport-scrollbar-problem/</guid>
      <description>&lt;p&gt;Today I learned that the viewport units in CSS don&amp;rsquo;t account for the width of visible classic scrollbars like on Windows.&lt;/p&gt;
&lt;p&gt;This means that if you use &lt;code&gt;width: 100vw&lt;/code&gt; to make an element the full width of the page and then a scrollbar appears, it will cause the element to overflow (by 17px which is apparently the width of Windows scrollbars) and create a horizontal scrollbar.&lt;/p&gt;
&lt;p&gt;CSS media queries don&amp;rsquo;t take them into account either, so if the viewport width is close (say within 17px) of a breakpoint then the appearance of a scrollbar will cause it to cross that threshold.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.smashingmagazine.com/2023/12/new-css-viewport-units-not-solve-classic-scrollbar-problem/#avoiding-the-classic-scrollbar-problem&#34;&gt;This article&lt;/a&gt; gives some potential solutions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use the new CSS container queries&lt;/li&gt;
&lt;li&gt;Use javascript to calculate the actual width&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another solution is to use javascript to replace the classic scollbars with overlay scrollbars like you see on mobile operating systems.
&lt;a href=&#34;https://kingsora.github.io/OverlayScrollbars/&#34;&gt;OverlayScrollbars&lt;/a&gt; is a popular js library that does this.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/viewport-scrollbar-problem/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Penpot</title>
      <link>https://www.brandonpugh.com/til/devtools/penpot/</link>
      <pubDate>Wed, 22 May 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/penpot/</guid>
      <description>&lt;p&gt;I just heard about a promising new design tool called &lt;a href=&#34;https://penpot.app/&#34;&gt;Penpot&lt;/a&gt; that positions itself as an open-source alternative to Figma.&lt;/p&gt;
&lt;p&gt;They recently added support for CSS grid layout which I&amp;rsquo;m looking forward to testing out.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.smashingmagazine.com/2024/04/penpot-css-grid-layout-designing-superpowers/&#34;&gt;https://www.smashingmagazine.com/2024/04/penpot-css-grid-layout-designing-superpowers/&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/penpot/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>BFCache</title>
      <link>https://www.brandonpugh.com/til/html/bfcache/</link>
      <pubDate>Tue, 21 May 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/bfcache/</guid>
      <description>&lt;p&gt;Today I learned that the Backwards/forwards cache (BFCache) is a thing.
This is the cache where the browser keeps a snapshot of a webpage so that it&amp;rsquo;s able to display almost instantly when a user clicks the back or forward buttons.&lt;/p&gt;
&lt;p&gt;This post gives a nice &lt;a href=&#34;https://www.sabatino.dev/bfcache-explained/&#34;&gt;overview of the BFCache&lt;/a&gt; and how it works — apparently &amp;ldquo;Chrome usage data shows that 1 in 10 navigations on desktop and 1 in 5 on mobile are either back or forward&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The Chrome Devtools also has a feature to let you &lt;a href=&#34;https://developer.chrome.com/docs/devtools/application/back-forward-cache&#34;&gt;test if your page is cacheable&lt;/a&gt; in the BFCache.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/bfcache/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Locally test on old version of Chrome</title>
      <link>https://www.brandonpugh.com/til/devtools/chromium-versions/</link>
      <pubDate>Mon, 20 May 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/chromium-versions/</guid>
      <description>&lt;p&gt;Today I learned that if you need to test in older versions of Chrome then you can &lt;a href=&#34;https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html&#34;&gt;download prior snapshots of Chromium builds&lt;/a&gt; as standalone executables.&lt;/p&gt;
&lt;p&gt;The tricky part is figuring out which build snapshot corresponds to which version of Chrome, which involves several steps detailed in the &lt;a href=&#34;https://www.chromium.org/getting-involved/download-chromium/#downloading-old-builds-of-chrome-chromium&#34;&gt;Chromium wiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Fortunately, someone put together a site to &lt;a href=&#34;https://vikyd.github.io/download-chromium-history-version/#/&#34;&gt;lookup by Chrome version&lt;/a&gt; and link to the correct build on the archive site.
Then you download and extract the zip file and run the single executable, i.e. &lt;code&gt;chrome.exe&lt;/code&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/chromium-versions/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Podman is a nice alternative to Docker</title>
      <link>https://www.brandonpugh.com/til/containers/podman/</link>
      <pubDate>Thu, 18 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/containers/podman/</guid>
      <description>&lt;p&gt;Today I learned that Podman is a pretty nice alternative to Docker, and in my case was a drop-in-replacement for Docker Desktop.&lt;/p&gt;
&lt;p&gt;The installation process was smooth and it really tries to guide you through the setup.&lt;/p&gt;
&lt;p&gt;They even provide cli aliases for docker commands so you don&amp;rsquo;t have to update any existing scripts.&lt;/p&gt;
&lt;p&gt;Proponents also argue that it has more secure default feature like rootless containers.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://betterstack.com/community/guides/scaling-docker/podman-vs-docker/&#34;&gt;Exploring Podman: A More Secure Docker Alternative&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/containers/podman/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Preload critical assets</title>
      <link>https://www.brandonpugh.com/til/html/preload-assets/</link>
      <pubDate>Wed, 13 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/preload-assets/</guid>
      <description>&lt;p&gt;Today I learned that you can preload critical assets in a page by using the &lt;code&gt;preload&lt;/code&gt; attribute on a link tag i.e. &lt;code&gt;&amp;lt;link rel=&amp;quot;preload&amp;quot;&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Especially useful for things like fonts that are discovered later by the browser.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://web.dev/articles/preload-critical-assets&#34;&gt;Preload critical assets to improve loading speed&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/preload-assets/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Shell Check</title>
      <link>https://www.brandonpugh.com/til/bash/shell-check/</link>
      <pubDate>Tue, 12 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/bash/shell-check/</guid>
      <description>&lt;p&gt;Today I learned about &lt;a href=&#34;https://www.shellcheck.net/&#34;&gt;ShellCheck&lt;/a&gt; which is essentially a linter for bash scripts.&lt;/p&gt;
&lt;p&gt;You can try it on the website but I recommend installing the &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck&#34;&gt;vscode extension&lt;/a&gt;.
I like that you can look up the rationale for each of the rules so it&amp;rsquo;s a great way to learn some best practices for bash scripts.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/bash/shell-check/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Windows Dev Drive</title>
      <link>https://www.brandonpugh.com/til/windows/dev-drive/</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/windows/dev-drive/</guid>
      <description>&lt;p&gt;Today I learned about a new feature in Windows 11 called &lt;a href=&#34;https://blog.maartenballiauw.be/post/2023/11/22/test-driving-windows-11-dev-drive-for-dotnet.html&#34;&gt;Dev Drive&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It sounds like it essentially lets you create an optimized drive or volume for heavy file I/O that could speed up large solutions or test suites.&lt;/p&gt;
&lt;p&gt;Doesn&amp;rsquo;t look like I&amp;rsquo;m able to enable this on my work laptop yet but I&amp;rsquo;m curious to try it on one of my personal machines and see if it&amp;rsquo;s a noticeable improvement.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://learn.microsoft.com/en-us/windows/dev-drive/&#34;&gt;Official docs&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/windows/dev-drive/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Truncate table</title>
      <link>https://www.brandonpugh.com/til/sql/truncate-table/</link>
      <pubDate>Tue, 20 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/sql/truncate-table/</guid>
      <description>&lt;p&gt;Today I learned that there is a &lt;code&gt;truncate table&lt;/code&gt; SQL command that deletes all data from a database table like &lt;code&gt;Delete from&lt;/code&gt; but is faster and uses fewer system and transaction log resources.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s supported in most database engines but there are likely caveats to keep in mind.&lt;/p&gt;
&lt;p&gt;For instance, with SQL Server:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It will reseed identity columns&lt;/li&gt;
&lt;li&gt;You can&amp;rsquo;t truncate tables that referenced in constraints&lt;/li&gt;
&lt;li&gt;and it requires ALTER table privileges&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For clearing out data in lower environments though, I&amp;rsquo;ve found it useful.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/sql/truncate-table/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Logical Properties</title>
      <link>https://www.brandonpugh.com/til/css/logical-properties/</link>
      <pubDate>Thu, 15 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/logical-properties/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve recently been learning about the new &lt;a href=&#34;https://web.dev/learn/css/logical-properties&#34;&gt;logical properties&lt;/a&gt; in CSS.&lt;/p&gt;
&lt;p&gt;Essentially if we&amp;rsquo;re developing applications for a global audience, instead of thinking in terms of right/left or top/bottom, we should start thinking in terms of &amp;ldquo;inline&amp;rdquo; and &amp;ldquo;block&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;These let us specify our styling and layouts in relative logical values instead of physical ones so they can adapt appropriately for right-to-left or vertical languages.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;margin-left: 20px&lt;/code&gt; would now be &lt;code&gt;margin-inline-start: 20px&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;These new properties are pretty well supported in browsers so I think it&amp;rsquo;s probably a good practice to try to default to using them when you can even if you don&amp;rsquo;t have any localization concerns.
For one, it doesn&amp;rsquo;t hurt to use them and you&amp;rsquo;re likely to start seeing them more and more in examples and documentation so you&amp;rsquo;ll want to get used to them.&lt;/p&gt;
&lt;p&gt;Plus you can use them as a convenient shorthand in some cases — for example, you can replace &lt;code&gt;margin-left: auto; margin-right: auto;&lt;/code&gt; with just &lt;code&gt;margin-inline: auto;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://css-tricks.com/css-logical-properties-and-values/&#34;&gt;CSS-Tricks article&lt;/a&gt; has a lot of good examples.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/logical-properties/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git Maintenance</title>
      <link>https://www.brandonpugh.com/til/git/git-maintanence/</link>
      <pubDate>Mon, 12 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/git-maintanence/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;a href=&#34;https://git-scm.com/docs/git-maintenance&#34;&gt;&lt;code&gt;git maintenance&lt;/code&gt;&lt;/a&gt; command that runs tasks for regular maintenance of a git repo.&lt;/p&gt;
&lt;p&gt;If you run &lt;code&gt;git maintenance start&lt;/code&gt; in a repo, git will create scheduled tasks to run at regular intervals to perform these tasks in the background like garbage collection.
This will optimize and speed up the repo without having to tack them on occasionally as you run other commands.&lt;/p&gt;
&lt;p&gt;A particularly handy task it will run every hour is &lt;code&gt;prefetch&lt;/code&gt;, where it does a &lt;code&gt;git fetch&lt;/code&gt; but only pulls down the data and doesn&amp;rsquo;t update any refs.
Then when you actually run &lt;code&gt;git fetch&lt;/code&gt; or &lt;code&gt;git pull&lt;/code&gt;, it completes almost instantly because it already has all the data.&lt;/p&gt;
&lt;p&gt;On Windows, you can view and tweak these tasks in the Task Scheduler and have names in the form of &lt;code&gt;Git Maintenance (&amp;lt;frequency&amp;gt;)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This also ties in well with my desire to be able to work offline if need be, since if I&amp;rsquo;m suddenly without internet but haven&amp;rsquo;t been running fetch all day, I can still run &lt;code&gt;git fetch&lt;/code&gt; and pull in all the changes from the day.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/git-maintanence/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Number.isInteger()</title>
      <link>https://www.brandonpugh.com/til/javascript/number-isinteger/</link>
      <pubDate>Thu, 08 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/number-isinteger/</guid>
      <description>&lt;p&gt;Today I learned that the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN&#34;&gt;&lt;code&gt;isNaN&lt;/code&gt;&lt;/a&gt; global function in javascript isn&amp;rsquo;t very useful for validating numbers.
The main reason is that it returns &lt;code&gt;false&lt;/code&gt; for an empty string since it coerces it to &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To add to the confusion, &lt;a href=&#34;https://stackoverflow.com/questions/33164725/confusion-between-isnan-and-number-isnan-in-javascript&#34;&gt;&lt;code&gt;Number.isNaN()&lt;/code&gt; behaves slightly differently&lt;/a&gt; since it just checks for the value &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For validation, I found &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger&#34;&gt;&lt;code&gt;Number.isInteger()&lt;/code&gt;&lt;/a&gt; to be the most useful.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/number-isinteger/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git ORIG_HEAD</title>
      <link>https://www.brandonpugh.com/til/git/orig-head/</link>
      <pubDate>Wed, 07 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/orig-head/</guid>
      <description>&lt;p&gt;Today I learned that &lt;code&gt;ORIG_HEAD&lt;/code&gt; is a reference that git maintains to the previous commit &lt;code&gt;HEAD&lt;/code&gt; pointed to before it &amp;ldquo;was modified in a drastic way&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The docs mention these operations as examples of when &lt;code&gt;ORIG_HEAD&lt;/code&gt; is updated: (git am, git merge, git rebase, git reset)&lt;/p&gt;
&lt;p&gt;This is useful when you want to undo one of those operations.&lt;/p&gt;
&lt;p&gt;You can use &lt;code&gt;git reset --hard ORIG_HEAD&lt;/code&gt; (or &lt;a href=&#34;https://www.brandonpugh.com/til/git/reset-keep/&#34;&gt;&lt;code&gt;--keep&lt;/code&gt;&lt;/a&gt;) to put your branch back to where it was before the operation.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/orig-head/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git rebase.abbreviateCommands</title>
      <link>https://www.brandonpugh.com/til/git/git-abbreviate-commands/</link>
      <pubDate>Fri, 02 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/git-abbreviate-commands/</guid>
      <description>&lt;p&gt;This is probably a very niche use case, but I learned today that you can abbreviate commands that git populates in the todo list during an interactive rebase.&lt;/p&gt;
&lt;p&gt;So instead of this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    pick deadbee The oneline of the commit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    pick fa1afe1 The oneline of the next commit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;It&amp;rsquo;ll look like this:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    p deadbee The oneline of the commit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    p fa1afe1 The oneline of the next commit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can enable this with &lt;code&gt;git config --global rebase.abbreviateCommands true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To be clear, you can always use the abbreviated commands, but since I use Vim to edit the list, it makes it slightly more convenient to edit the commands.&lt;/p&gt;
&lt;p&gt;For instance, before when the command was &lt;code&gt;pick&lt;/code&gt;, and I wanted to squash a commit, I would jump to the line, type &lt;code&gt;ciw&lt;/code&gt; to delete the word &lt;code&gt;pick&lt;/code&gt; and enter insert mode, then type &lt;code&gt;s&lt;/code&gt; and then &lt;code&gt;esc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But when the command is &lt;code&gt;p&lt;/code&gt;, I can just type &lt;code&gt;r&lt;/code&gt; and &lt;code&gt;s&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So if you&amp;rsquo;re counting, that&amp;rsquo;s &lt;strong&gt;three&lt;/strong&gt; fewer keystrokes for each command. Mission. Accomplished.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/git-abbreviate-commands/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>font-variant-numeric</title>
      <link>https://www.brandonpugh.com/til/css/font-variant-numeric/</link>
      <pubDate>Thu, 01 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/font-variant-numeric/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;code&gt;font-variant-numeric&lt;/code&gt; CSS property that lets you control alternate glyphs for numbers.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;visual examples of the different values of font-variant-numeric&#34; loading=&#34;lazy&#34; src=&#34;font-variant-numeric.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Not every font will support all of these but the &lt;code&gt;tabular-nums&lt;/code&gt; option is common and seems especially useful for data in grids.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://textlab.dev/posts/font-variant-numeric&#34;&gt;Using Font Variant Numeric&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/font-variant-numeric/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Javascript Array `with()` method</title>
      <link>https://www.brandonpugh.com/til/javascript/array-with-method/</link>
      <pubDate>Wed, 31 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/array-with-method/</guid>
      <description>&lt;p&gt;Today I learned that there&amp;rsquo;s a new javascript array method that returns a &lt;em&gt;new&lt;/em&gt; array with the element at the given index replaced with the given value.&lt;/p&gt;
&lt;p&gt;Convenient for manipulating array values without mutating the original array.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;arr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// [1, 2, 6, 4, 5]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// [1, 2, 3, 4, 5]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/array-with-method/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>sourceURL pragma</title>
      <link>https://www.brandonpugh.com/til/devtools/inline-script-sourceurl/</link>
      <pubDate>Mon, 29 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/inline-script-sourceurl/</guid>
      <description>&lt;p&gt;Today I learned that you can add &lt;code&gt;//# sourceURL=&amp;lt;anything&amp;gt;.js&lt;/code&gt; special comment to an inline script tag to have it show up as a separate javascript file in the dev tools sources tab.&lt;/p&gt;
&lt;p&gt;This makes it a bit easier to work with especially when you have a huge inline script tag you&amp;rsquo;re dealing with.&lt;/p&gt;
&lt;p&gt;It even works with &lt;code&gt;eval()&lt;/code&gt; too if you&amp;rsquo;re unfortunate enough to be dealing with that.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of an inline script showing as a separate .js file in devtools&#34; loading=&#34;lazy&#34; src=&#34;inline-script-sourceurl.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://devtoolstips.org/tips/en/name-evaluated-files/&#34;&gt;https://devtoolstips.org/tips/en/name-evaluated-files/&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/inline-script-sourceurl/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>CSP `connect-src` directive</title>
      <link>https://www.brandonpugh.com/til/html/csp-connect-src/</link>
      <pubDate>Fri, 26 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/csp-connect-src/</guid>
      <description>&lt;p&gt;Today I learned that there is a Content-Security-Policy (CSP) directive &lt;code&gt;connect-src&lt;/code&gt; that you can use to restrict all outgoing requests from your website to only the domains that you specify.&lt;/p&gt;
&lt;p&gt;This is a powerful mitigation against any kind of script injection attacks since no data can then be exfiltrated from your page.&lt;/p&gt;
&lt;p&gt;It applies to &lt;code&gt;XMLHttpRequest&lt;/code&gt; (AJAX), &lt;code&gt;WebSocket&lt;/code&gt;, &lt;code&gt;fetch()&lt;/code&gt;, &lt;code&gt;&amp;lt;a ping&amp;gt;&lt;/code&gt; or &lt;code&gt;EventSource&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;CSP is an HTTP response header for enhancing the security of a site and there are of course several other directives you might want to enable.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://content-security-policy.com/&#34;&gt;This is a handy reference&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to see a real-world comprehensive example, take a look at the &lt;a href=&#34;https://report-uri.com/home/analyse/https%3A%2F%2Fhaveibeenpwned.com%2F&#34;&gt;CSP header for haveibeenpwned.com&lt;/a&gt; (this links to &lt;a href=&#34;https://report-uri.com/home/analyse&#34;&gt;the csp analyser from report-uri&lt;/a&gt;).&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/csp-connect-src/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Disable entire form</title>
      <link>https://www.brandonpugh.com/til/html/disable-form/</link>
      <pubDate>Wed, 24 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/disable-form/</guid>
      <description>&lt;p&gt;Today I learned that you can disable an entire form by wrapping all the inputs in a &lt;code&gt;&amp;lt;fieldset disabled&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You might think that you can disable a form with &lt;code&gt;&amp;lt;form disabled&amp;gt;&lt;/code&gt; but unfortunately, the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form&#34;&gt;form element&lt;/a&gt; doesn&amp;rsquo;t have a disabled attribute.&lt;/p&gt;
&lt;p&gt;Fieldsets are typically used to group related form elements (and in some cases can improve accessibility) — so you can have multiple in a form and disable portions of the form separately.&lt;/p&gt;
&lt;p&gt;This is much more convenient than having to toggle the &lt;code&gt;disabled&lt;/code&gt; attributes on every form element.&lt;/p&gt;
&lt;p&gt;I also learned that there is a difference between styling a button with &lt;code&gt;button:disabled&lt;/code&gt; and &lt;code&gt;button[disabled]&lt;/code&gt;, the former being the one you want to use in this case since the latter only matches a button with a disabled attribute.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://linkedlist.ch/disabling_an_entire_form_in_html_37/&#34;&gt;Disabling an entire form in HTML&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/disable-form/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git clean interactive</title>
      <link>https://www.brandonpugh.com/til/git/git-clean/</link>
      <pubDate>Tue, 23 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/git-clean/</guid>
      <description>&lt;p&gt;I just discovered the interactive mode of &lt;code&gt;git clean&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Git Clean is handy when you want to clear out anything from your local repository folder that isn&amp;rsquo;t tracked by git. This often includes build outputs and other generated files. This is useful if for instance Visual Studio is acting weird and you&amp;rsquo;re tempted to do a fresh clone to fix it.&lt;/p&gt;
&lt;p&gt;I have a git alias I use for this: &lt;code&gt;cl = git clean -idx -e &#39;node_modules&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This tells git to delete any untracked files including anything ignored by &lt;code&gt;.gitignore&lt;/code&gt; so it&amp;rsquo;s practically the same as doing a fresh clone (except you&amp;rsquo;ll keep work in progress). The &lt;code&gt;-i&lt;/code&gt; is interactive so git shows you everything it&amp;rsquo;ll delete and you can confirm it. I used to use &lt;code&gt;-f&lt;/code&gt; for force but the interactive mode is pretty nice and it&amp;rsquo;s just a couple of extra keystrokes to blow everything way if I want.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;-e &#39;node_modules&#39;&lt;/code&gt; is optional but if it&amp;rsquo;s a dotnet build issue I&amp;rsquo;m having then I don&amp;rsquo;t want to waste time deleting and reinstalling npm modules so this tells git not to touch any &lt;code&gt;node_modules&lt;/code&gt; in the repo.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/git-clean/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>DeepGit blame</title>
      <link>https://www.brandonpugh.com/til/git/deepgit/</link>
      <pubDate>Fri, 19 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/deepgit/</guid>
      <description>&lt;p&gt;Today I learned that &lt;a href=&#34;https://www.syntevo.com/deepgit/tour/&#34;&gt;DeepGit&lt;/a&gt; is actually completely free even for commercial use. This is the best git blame utility I&amp;rsquo;ve come across because it lets you continue drilling down into the history of a line, kinda like a recursive blame.
You do have to provide an email address to register but I think it&amp;rsquo;s worth it.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s from the same developer of my preferred git client SmartGit but SmartGit &lt;em&gt;does&lt;/em&gt; require a paid license for commercial use.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/deepgit/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Fix package-lock.json merge conflicts</title>
      <link>https://www.brandonpugh.com/til/node/package-lock-conflicts/</link>
      <pubDate>Tue, 16 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/node/package-lock-conflicts/</guid>
      <description>&lt;p&gt;Today I learned that npm can handle merge conflicts in your &lt;code&gt;package-lock.json&lt;/code&gt; file for you.&lt;/p&gt;
&lt;p&gt;After you resolve any merge conflicts in your &lt;code&gt;package.json&lt;/code&gt;, you can just run &lt;code&gt;npm install [--package-lock-only]&lt;/code&gt; and npm will resolve the conflicts in the lock file.
If &lt;code&gt;--package-lock-only&lt;/code&gt; is provided, it will do this without also modifying your local &lt;code&gt;node_modules/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://tkdodo.eu/blog/solving-conflicts-in-package-lock-json&#34;&gt;Solving conflicts in package-lock.json&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/node/package-lock-conflicts/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Dynamically darken or lighten a color in CSS</title>
      <link>https://www.brandonpugh.com/til/css/darken-colors-color-mix/</link>
      <pubDate>Mon, 15 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/darken-colors-color-mix/</guid>
      <description>&lt;p&gt;Today I learned that you can now easily darken or lighten a color natively in CSS with the new &lt;a href=&#34;https://developer.chrome.com/docs/css-ui/css-color-mix&#34;&gt;color-mix&lt;/a&gt; function.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a use case I run into a lot where you have a primary brand color and you need to darken it on hover:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;root&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nv&#34;&gt;--brand-color-dark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;color-mix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;oklab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;brand&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;black&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nv&#34;&gt;--brand-color-light&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;color-mix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;oklab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;brand&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;white&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;button&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;hover&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;brand&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This works by mixing the color with some amount of black or white. I also chose the &lt;code&gt;oklab&lt;/code&gt; &lt;a href=&#34;https://developer.chrome.com/docs/css-ui/high-definition-css-color-guide#meet_the_new_web_color_spaces&#34;&gt;color space&lt;/a&gt; since it&amp;rsquo;s the most likely to produce what I&amp;rsquo;m expecting for this use case.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve accomplished this before by using HSL color values with CSS variables and manipulating the lightness channel but this is much nicer and works even if the base color is defined as a hex value (that may or may not come from a database somewhere).&lt;/p&gt;
&lt;p&gt;I was missing something like this from preprocessors like LESS and SASS and as of 2023 this is supported in all modern browsers.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/darken-colors-color-mix/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Thin Space</title>
      <link>https://www.brandonpugh.com/til/html/thin-space/</link>
      <pubDate>Fri, 12 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/thin-space/</guid>
      <description>&lt;p&gt;Today I learned that there is an HTML entity called &amp;ldquo;thin space&amp;rdquo; that you can use when you need less space between two characters than the normal space.&lt;/p&gt;
&lt;p&gt;The HTML code is &lt;code&gt;&amp;amp;thinsp;&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thin Space might be the most underrated HTML entity. It can be used for a name like J. K. Simmons. Without spacing, the J and K would seem too close together; with a regular space, they seem too far apart. Insert a thin space and it is just perfect. - &lt;a href=&#34;https://codepen.io/mikemai2awesome/full/qBygNwq&#34;&gt;Typography Manual&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://codepen.io/mikemai2awesome/pen/LYQwBmp&#34;&gt;You can see a demo here&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/thin-space/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Copy Nice Extension</title>
      <link>https://www.brandonpugh.com/til/visual-studio/copy-nice/</link>
      <pubDate>Wed, 10 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/visual-studio/copy-nice/</guid>
      <description>&lt;p&gt;Today I learned about a handy little Visual Studio extension called &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=MadsKristensen.CopyNice&#34;&gt;Copy Nice&lt;/a&gt; whose sole purpose is to address an annoyance I encounter frequently where the indentation is off when I copy and paste code snippets.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;code snippet with bad indentation&#34; loading=&#34;lazy&#34; src=&#34;copy-nice.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;With this extension, when code is copied it will automatically be formatted to take care of the leading indentation issue.&lt;/p&gt;
&lt;p&gt;Now if only there was some system-level utility to this do when copying from anywhere&amp;hellip;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/visual-studio/copy-nice/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Smooth scrolling</title>
      <link>https://www.brandonpugh.com/til/css/smooth-scrolling/</link>
      <pubDate>Mon, 08 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/smooth-scrolling/</guid>
      <description>&lt;p&gt;Today I learned that you can now implement smooth scrolling purely with CSS in modern browsers.&lt;/p&gt;
&lt;p&gt;By adding the following CSS:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* Smooth scrolling IF user doesn&amp;#39;t have a preference due to motion sensitivities */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;media&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;screen&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;prefers-reduced-motion&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;no-preference&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;html&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;scroll-behavior&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;smooth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the browser will scroll smoothly whenever scrolling is triggered either by Javascript (with something like &lt;code&gt;document.documentElement.scrollTop = 0&lt;/code&gt;) or by linking to elements with an internal anchor link.
It&amp;rsquo;s considered best practice to use the &lt;code&gt;prefers-reduced-motion&lt;/code&gt; media query to only enable things like animations to be mindful of users with motion sensitivities.
In my testing, however, the browser won&amp;rsquo;t ever smooth scroll if the user has &lt;code&gt;prefers-reduced-motion&lt;/code&gt; enabled.&lt;/p&gt;
&lt;p&gt;Another way of accomplishing this is with the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo&#34;&gt;&lt;code&gt;scrollTo&lt;/code&gt;&lt;/a&gt; function in javascript:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;window.scrollTo({top:0, behavior: &#39;smooth&#39;})&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;or with the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView&#34;&gt;scrollIntoView&lt;/a&gt; function.&lt;/p&gt;
&lt;p&gt;I also discovered that &lt;code&gt;prefers-reduced-motion&lt;/code&gt; is controlled at the system level — in Windows it&amp;rsquo;s determined by the &amp;ldquo;Show animations in Windows&amp;rdquo; setting which is automatically disabled when connecting to Windows via Remote Desktop.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior&#34;&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/smooth-scrolling/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Quit vim with :x</title>
      <link>https://www.brandonpugh.com/til/vim/quit-with-x/</link>
      <pubDate>Sun, 07 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/quit-with-x/</guid>
      <description>&lt;p&gt;People like to joke that vim is impossible to exit, but I just discovered that there are actually &lt;a href=&#34;https://hashrocket.com/blog/posts/how-to-quit-vim&#34;&gt;several different ways&lt;/a&gt; to quit and &lt;code&gt;:x&lt;/code&gt; is my new favorite.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;:x&lt;/code&gt; command will save and quit but it differs from &lt;code&gt;:wq&lt;/code&gt; in that it will only write the file to disc if there were any changes so the &lt;em&gt;modified date&lt;/em&gt; of the file won&amp;rsquo;t get updated unnecessarily.&lt;/p&gt;
&lt;p&gt;This seems like the preferred behavior most of the time.
That coupled with the fact that it&amp;rsquo;s slightly faster to type has made it my new default way to exit vim.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/quit-with-x/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Easily reference upstream branch</title>
      <link>https://www.brandonpugh.com/til/git/reference-upstream-branch/</link>
      <pubDate>Thu, 04 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/reference-upstream-branch/</guid>
      <description>&lt;p&gt;Today I learned that you can reference the upstream branch in git with &lt;code&gt;@{u}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I used this to make a convenient git alias &lt;code&gt;reso&lt;/code&gt; for &amp;ldquo;reset to origin&amp;rdquo;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git config --global alias.reso &lt;span class=&#34;s2&#34;&gt;&amp;#34;reset --keep @{u}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;note: I&amp;rsquo;m using &lt;code&gt;--keep&lt;/code&gt; instead of &lt;code&gt;--hard&lt;/code&gt; because it&amp;rsquo;s a bit &lt;a href=&#34;https://www.brandonpugh.com/til/git/reset-keep/&#34;&gt;safer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I use this when a branch I&amp;rsquo;ve pulled down has completely changed on the remote and I have no changes (for instance when reviewing a PR) and a &lt;code&gt;pull&lt;/code&gt; would be messy (a reset is also much faster depending on the number of commits).&lt;/p&gt;
&lt;p&gt;Or if I&amp;rsquo;ve completely borked my local branch and want to start over from where I last pushed 😅.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/reference-upstream-branch/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title></title>
      <link>https://www.brandonpugh.com/til/typescript/strongly-typed-id/</link>
      <pubDate>Tue, 19 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/typescript/strongly-typed-id/</guid>
      <description>&lt;h1&gt;&lt;/h1&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/typescript/strongly-typed-id/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Collection expressions</title>
      <link>https://www.brandonpugh.com/til/csharp/collection-expressions/</link>
      <pubDate>Thu, 14 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/csharp/collection-expressions/</guid>
      <description>&lt;p&gt;Today I learned that C# 12 is getting some nice javascript-like syntax with collection expressions and the &lt;code&gt;..&lt;/code&gt; (spread operator):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;moreFruits&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;orange&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;pear&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;IEnumerable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fruits&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;apple&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;banana&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;cherry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;..&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;moreFruits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note though that the spread operator is only 2 dots instead of 3 dots like in javascript.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/csharp/collection-expressions/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Local overrides in Chrome DevTools</title>
      <link>https://www.brandonpugh.com/til/devtools/local-overrides/</link>
      <pubDate>Mon, 11 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/local-overrides/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;a href=&#34;https://developer.chrome.com/docs/devtools/overrides&#34;&gt;local overrides&lt;/a&gt; feature of Chrome Devtools that lets you &amp;ldquo;you can override HTTP response headers and web content, including XHR and fetch requests, to mock remote resources even if you don&amp;rsquo;t have access to them&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;This came in handy for me when trying to debug an issue that I wasn&amp;rsquo;t able to reproduce locally. The official docs do a nice job showing how to enable the feature but just make sure you delete the override once you&amp;rsquo;re done otherwise you might wonder why the page has stopped updating.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://developer.chrome.com/docs/devtools/overrides&#34;&gt;https://developer.chrome.com/docs/devtools/overrides&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/local-overrides/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Add alt text to presentation slides</title>
      <link>https://www.brandonpugh.com/til/google/alt-text-google-slides/</link>
      <pubDate>Wed, 06 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/google/alt-text-google-slides/</guid>
      <description>&lt;p&gt;Today I learned that you can add alt text to images in PowerPoint and Google Slides by right-clicking on an image.
It hadn&amp;rsquo;t occurred to me before but it makes sense that it would be as important as alt text for images on the web if you&amp;rsquo;re going to share your slides.
Likewise, you should mark an image as &amp;ldquo;decorative&amp;rdquo; if you want a screen reader to ignore it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://axesslab.com/alt-texts/&#34;&gt;This post&lt;/a&gt; has some nice examples of how to write good alt text.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/google/alt-text-google-slides/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Display the week number in Google Calendar</title>
      <link>https://www.brandonpugh.com/til/google/show-week-number-calendar/</link>
      <pubDate>Tue, 05 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/google/show-week-number-calendar/</guid>
      <description>&lt;p&gt;Today I learned that you can configure both Google Calendar and Outlook to show the week number in the &amp;ldquo;month&amp;rdquo; view.&lt;/p&gt;
&lt;p&gt;You might find this handy for project/sprint planning — I&amp;rsquo;ve also been keeping weekly notes with the week number at the beginning of the filename.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/google/show-week-number-calendar/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Open a URL in vim with `gx`</title>
      <link>https://www.brandonpugh.com/til/vim/vim-open-url/</link>
      <pubDate>Mon, 04 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/vim-open-url/</guid>
      <description>&lt;p&gt;Pressing &lt;code&gt;gx&lt;/code&gt; while over a URL in vim will open that url.&lt;/p&gt;
&lt;p&gt;Confirmed it also works in vscode-vim.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/vim-open-url/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Flow spacing and the lobotomized owl</title>
      <link>https://www.brandonpugh.com/til/css/flow-spacing/</link>
      <pubDate>Wed, 29 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/flow-spacing/</guid>
      <description>&lt;p&gt;This is another #til by proxy. A teammate asked about a CSS selector I used which has come to be referred to as the &lt;a href=&#34;https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/&#34;&gt;&amp;ldquo;lobotomized owl&amp;rdquo;&lt;/a&gt; (&lt;code&gt;* + *&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;flow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;margin-top&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flow&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;space&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;em&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What this does is select every child element of the &lt;code&gt;.flow&lt;/code&gt; class except the first one.&lt;/p&gt;
&lt;p&gt;You can also use newer CSS selectors to do the same thing in a way that might be more obvious:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;flow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;where&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;first-child&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;margin-top&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flow&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;space&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;em&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above snippet is probably my favorite CSS utility called &lt;a href=&#34;https://24ways.org/2018/managing-flow-and-rhythm-with-css-custom-properties/&#34;&gt;flow spacing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a nice way to easily add consistent spacing between elements in your project and because css variables cascade, it&amp;rsquo;s easy to override for specific contexts within different classes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;flow--space-compact&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nv&#34;&gt;--flow-space&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;.75&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;em&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or with inline styles: &lt;code&gt;&amp;lt;footer class=&amp;quot;flow&amp;quot; style=&amp;quot;--flow-space: 2em&amp;quot;&amp;gt;&amp;lt;/footer&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m in the camp that parent components should be responsible for spacing out their child components and this utility makes that easier to do with consistency.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/flow-spacing/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Trim videos without re-encoding</title>
      <link>https://www.brandonpugh.com/til/video/trim-without-reencoding/</link>
      <pubDate>Mon, 27 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/video/trim-without-reencoding/</guid>
      <description>&lt;p&gt;Today I learned that &lt;a href=&#34;https://ffmpeg.org/&#34;&gt;FFmpeg&lt;/a&gt; is the easiest (only?) way to trim/cut a video without re-encoding it.&lt;/p&gt;
&lt;p&gt;You can specify a start and stop time like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i input.mp4 -ss 00:01:30.000 -to 00:04:05.000 -c copy output.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The key is the &lt;code&gt;-c copy&lt;/code&gt; parameter which will just copy the data frames for operations where they don&amp;rsquo;t need to be modified.
This is nice because it&amp;rsquo;s &lt;em&gt;way&lt;/em&gt; faster than decoding and re-encoding and you don&amp;rsquo;t have any loss in quality if you&amp;rsquo;re not working with a raw format.&lt;/p&gt;
&lt;p&gt;It also works for removing/replacing the audio of a video.
This &lt;a href=&#34;https://img.ly/blog/ultimate-guide-to-ffmpeg/#cut-and-trim-without-reencoding&#34;&gt;ultimate guide&lt;/a&gt; is really handy.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/video/trim-without-reencoding/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>The `datalist` HTML element</title>
      <link>https://www.brandonpugh.com/til/html/datalist/</link>
      <pubDate>Mon, 20 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/datalist/</guid>
      <description>&lt;p&gt;Today I learned that there&amp;rsquo;s now an HTML element called &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist&#34;&gt;&lt;code&gt;datalist&lt;/code&gt;&lt;/a&gt; that&amp;rsquo;s basically an autocomplete-like input element.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/datalist/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Dependency Review</title>
      <link>https://www.brandonpugh.com/til/github/dependency-review/</link>
      <pubDate>Wed, 15 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/github/dependency-review/</guid>
      <description>&lt;p&gt;Today I learned that Github has a cool &lt;a href=&#34;https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/reviewing-dependency-changes-in-a-pull-request&#34;&gt;dependency review&lt;/a&gt; feature for pull requests.&lt;/p&gt;
&lt;p&gt;If a dependency file like a &lt;code&gt;package.json&lt;/code&gt; or &lt;code&gt;.csproj&lt;/code&gt; has been modified, you can click on the &amp;ldquo;rich diff&amp;rdquo; button and it will list out any dependencies that changed or any vulnerabilities for those versions. It&amp;rsquo;ll even list out sub-dependencies in a &lt;code&gt;package-lock.json&lt;/code&gt; which is otherwise pretty inscrutable.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of package.json rich diff&#34; loading=&#34;lazy&#34; src=&#34;dependency-review.png&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/github/dependency-review/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Disabled buttons are bad for accessibility</title>
      <link>https://www.brandonpugh.com/til/html/disabled-buttons-bad-accessibility/</link>
      <pubDate>Fri, 10 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/disabled-buttons-bad-accessibility/</guid>
      <description>&lt;p&gt;Today I learned that disabled buttons are potentially bad for accessibility.&lt;/p&gt;
&lt;p&gt;I realized long ago that disabled buttons can be bad for UX but I just saw Chris Ferdinandi&amp;rsquo;s post &lt;a href=&#34;https://gomakethings.com/dont-disable-buttons/&#34;&gt;Don&amp;rsquo;t Disable Buttons&lt;/a&gt;, and learned that disabled buttons aren&amp;rsquo;t focusable which means they don&amp;rsquo;t work well with screen readers or navigating with the keyboard.&lt;/p&gt;
&lt;p&gt;I usually recommend against disabling form submit buttons when there are validation errors because the user has no feedback as to &lt;em&gt;why&lt;/em&gt; it&amp;rsquo;s disabled, but Chris gives the example of disabling while the form is being submitted (which I&amp;rsquo;ve probably done in the past) and he goes into detail about the issues with this approach and a good alternative.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/disabled-buttons-bad-accessibility/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>`lh` and `rlh` units</title>
      <link>https://www.brandonpugh.com/til/css/line-height-units/</link>
      <pubDate>Thu, 09 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/line-height-units/</guid>
      <description>&lt;p&gt;Today I learned that there are new &lt;a href=&#34;https://css-tricks.com/lh-and-rlh-units/&#34;&gt;line height&lt;/a&gt; units in CSS.
The &lt;code&gt;lh&lt;/code&gt; unit is “equal to the computed value of line-height”.&lt;/p&gt;
&lt;p&gt;If nothing else this will be nice for a small annoyance I&amp;rsquo;ve run into before of vertically centering icons:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot showing the difference vertically aligning icon with lh and em&#34; loading=&#34;lazy&#34; src=&#34;line-height-screenshot.png&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/line-height-units/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Native node import path aliases</title>
      <link>https://www.brandonpugh.com/til/node/import-aliases/</link>
      <pubDate>Wed, 08 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/node/import-aliases/</guid>
      <description>&lt;p&gt;Today I learned that node natively supports import path aliases with the &lt;a href=&#34;https://nodejs.org/api/packages.html#imports&#34;&gt;imports field&lt;/a&gt; in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The nice thing about this is that they&amp;rsquo;re supported by most node tools now so you don&amp;rsquo;t need to configure your aliases separately in different tools like eslint, webpack, vite, etc&amp;hellip;&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re not familiar with import aliases, they&amp;rsquo;re a handy way to avoid unwieldy relative import paths.&lt;/p&gt;
&lt;p&gt;instead of:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;utils&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;../../../../shared/utils&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;you can have:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;utils&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;#shared/utils&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A nice config to start with is something similar to:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;imports&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;#*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;./*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which lets you import anything from the root of your project.&lt;/p&gt;
&lt;p&gt;I actually discovered this from looking through the &lt;a href=&#34;https://github.com/epicweb-dev/epic-stack/blob/main/docs/decisions/031-imports.md&#34;&gt;decision log&lt;/a&gt; of the &lt;a href=&#34;https://github.com/epicweb-dev/epic-stack&#34;&gt;&lt;code&gt;epic-stack&lt;/code&gt;&lt;/a&gt; react project.&lt;/p&gt;
&lt;p&gt;Unfortunately typescript doesn&amp;rsquo;t support it yet (though it&amp;rsquo;s planned), so you&amp;rsquo;d still need to update &lt;code&gt;tsconfig.json&lt;/code&gt; with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;paths&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;#*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;./*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/node/import-aliases/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Override nested dependencies with npm</title>
      <link>https://www.brandonpugh.com/til/node/npm-overrides/</link>
      <pubDate>Mon, 06 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/node/npm-overrides/</guid>
      <description>&lt;p&gt;Today I learned that as of npm cli v8.3.0 (2021-12-09), you can use the &lt;a href=&#34;https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides&#34;&gt;overrides field&lt;/a&gt; in &lt;code&gt;package.json&lt;/code&gt; to &amp;ldquo;override&amp;rdquo; nested dependency versions.&lt;/p&gt;
&lt;p&gt;This is handy for several scenarios, but for me I used for a third-party react component that has a &lt;code&gt;peerDependency&lt;/code&gt; on v16 of react even though it works just fine with v18 but it isn&amp;rsquo;t under active development at the moment so I had to override the version it accepts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;overrides&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;react-input-range&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;react-dom&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;^18.2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;react&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;^18.2.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yarn has similar functionality that it calls &lt;a href=&#34;https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/&#34;&gt;resolutions&lt;/a&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/node/npm-overrides/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use ChatGPT to help you write architectural decision records</title>
      <link>https://www.brandonpugh.com/til/ai/chatgpt-to-help-write-adr/</link>
      <pubDate>Fri, 03 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/ai/chatgpt-to-help-write-adr/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been discovering recently that ChatGPT is actually pretty good at helping write &lt;a href=&#34;https://adr.github.io/&#34;&gt;Architectural Decision Records (ADRs)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Like most writing tasks, I&amp;rsquo;m finding ChatGPT is good at giving me a nice starting point instead of staring a blank template.&lt;/p&gt;
&lt;p&gt;Even with as simple a prompt as &amp;ldquo;write an architectural decision record on why we chose to go with react instead of angular&amp;rdquo;, it&amp;rsquo;ll give a decent list of pros and cons on the topic in a common ADR template.
I can also refine it further by saying &amp;ldquo;write it using the following template instead&amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I really like ADRs for capturing &lt;strong&gt;&lt;em&gt;why&lt;/em&gt;&lt;/strong&gt; we made a particular decision and the important points we considered and which things might have been deal breakers - which ChatGPT obviously can&amp;rsquo;t do for you but it&amp;rsquo;s a quick way to list out some points and occasionally it&amp;rsquo;ll even mention something I hadn&amp;rsquo;t considered.&lt;/p&gt;
&lt;p&gt;I also like asking it to argue the reverse like: &amp;ldquo;write an architectural decision record on why we chose to go with &lt;em&gt;angular instead of react&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Interestingly, it will show the result in the UI as the rendered markdown but when you click the &amp;ldquo;copy&amp;rdquo; button it will copy the source markdown which is nice.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/ai/chatgpt-to-help-write-adr/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Blob URLs</title>
      <link>https://www.brandonpugh.com/til/html/blob-url/</link>
      <pubDate>Thu, 02 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/blob-url/</guid>
      <description>&lt;p&gt;Today I learned that in a web page, when you&amp;rsquo;re working with Blob or File objects you can call &lt;code&gt;URL.createObjectURL()&lt;/code&gt; to create a Blob URL that can be used as the source for anything that normally takes a URL like images or download links.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s also apparently a good alternative to base64 encoded Data-URIs especially when dealing with larger amounts of data since a base64 encoded file will be 33% larger than the raw binary.&lt;/p&gt;
&lt;p&gt;I was running into issues trying to embed a large PDF with the &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt; element and instead of setting a massive base64 string as the data source, I was able to convert it to a blob and use a blob url so it ends up looking something like:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;object data=&amp;quot;blob:https://localhost/d827ea99-9e80-496a-a8e0-e107b83080e9&amp;quot; type=&amp;quot;application/pdf&amp;quot;&amp;gt;&amp;lt;/object&amp;gt;&lt;/code&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/blob-url/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>`every()` returns true for an empty array</title>
      <link>https://www.brandonpugh.com/til/javascript/every-returns-true-empty-array/</link>
      <pubDate>Wed, 01 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/every-returns-true-empty-array/</guid>
      <description>&lt;p&gt;Today I learned that the javascript array method &lt;code&gt;.every()&lt;/code&gt; will always return true for an empty array.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;every&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;         &lt;span class=&#34;c1&#34;&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;every&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;           &lt;span class=&#34;c1&#34;&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;every&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;          &lt;span class=&#34;c1&#34;&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For me at least, this was a bit surprising and I realized I&amp;rsquo;d been thinking about this function works incorrectly.
Your first thought might be that this is another one of javascript&amp;rsquo;s quirks, but this is actually how most languages implement similar functions including Rust, Python, and C#:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;All&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;All&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Apparently this is because of Math. Specifically, it&amp;rsquo;s meant to behave the same as the &amp;ldquo;for all&amp;rdquo; quantifier in mathematics.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://humanwhocodes.com/blog/2023/09/javascript-wtf-why-does-every-return-true-for-empty-array/#user-content-fn-10&#34;&gt;Nicholas Zakas has a good article&lt;/a&gt; that goes into more detail and this nice tip if you also found this behavior surprising:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Instead of reading every() as “does every item in this array match this condition?” read it as, “is there any item in this array that doesn’t match this condition?”&lt;/p&gt;
&lt;/blockquote&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/every-returns-true-empty-array/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Update git credentials in Windows</title>
      <link>https://www.brandonpugh.com/til/git/update-credentials/</link>
      <pubDate>Fri, 20 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/update-credentials/</guid>
      <description>&lt;p&gt;Today I learned that if you need to update (or delete) credentials that were previously saved with the &lt;code&gt;git-credential-manager&lt;/code&gt;, then you have to go the Windows Credential Manager.&lt;/p&gt;
&lt;p&gt;Find it under &lt;code&gt;Control Panel -&amp;gt; Credential Manager -&amp;gt; Generic Credentials&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://cmatskas.com/how-to-update-your-git-credentials-on-windows/&#34;&gt;Read more&lt;/a&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/update-credentials/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Calling an extension method on a null instance</title>
      <link>https://www.brandonpugh.com/til/csharp/string-extension-method/</link>
      <pubDate>Thu, 19 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/csharp/string-extension-method/</guid>
      <description>&lt;p&gt;Today I learned that you can call an extension method on a null instance of the type.
I had always assumed without thinking about it too hard, that the reason &lt;code&gt;string.IsNullOrEmpty&lt;/code&gt; isn&amp;rsquo;t defined as an extension method in the framework is because you would get &lt;code&gt;NullReferenceException&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But if we were to define an extension method like &lt;code&gt;public static bool IsNullOrEmpty(this string s)&lt;/code&gt;, and call it like &lt;code&gt;if(s.IsNullOrEmpty())&lt;/code&gt;
this is just syntactic sugar for &lt;code&gt;if(StringExtensions.IsNullOrEmpty(s))&lt;/code&gt; and therefore it&amp;rsquo;s safe to call on a null instance.&lt;/p&gt;
&lt;p&gt;Apparently the argument against this is that it could be confusing or counterintuitive when looking at the code if you think it&amp;rsquo;s an instance method.
I personally fall on the side of adding convenient extension methods like this - if nothing else to add a &lt;code&gt;NotNullOrEmpty&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;To me I&amp;rsquo;ve always found it very easy to miss the &lt;code&gt;!&lt;/code&gt; operator in a conditional and so avoiding those makes the condition much easier to read.&lt;/p&gt;
&lt;p&gt;I much perfer:&lt;br&gt;
&lt;code&gt;if(userName.NotNullOrEmpty)&lt;/code&gt;&lt;br&gt;
over&lt;br&gt;
&lt;code&gt;if(!string.IsNullOrEmpty(userName))&lt;/code&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/csharp/string-extension-method/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Zeal offline documentation browser</title>
      <link>https://www.brandonpugh.com/til/documentation/zeal/</link>
      <pubDate>Wed, 18 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/documentation/zeal/</guid>
      <description>&lt;p&gt;Today I learned about a cool project called &lt;a href=&#34;https://zealdocs.org/&#34;&gt;Zeal&lt;/a&gt; that let&amp;rsquo;s download and browse the documentation for a bunch of projects.
I&amp;rsquo;ve always liked the idea being able to continue working even without internet.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/documentation/zeal/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Conditional logic in pipelines YAML</title>
      <link>https://www.brandonpugh.com/til/azure-devops/conditional-yaml/</link>
      <pubDate>Mon, 16 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/azure-devops/conditional-yaml/</guid>
      <description>&lt;p&gt;Today I learned that you can have conditional expressions in Azure Pipelines YAML files:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ if parameters.debug }}:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;TOOL_DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;TOOL_DEBUG_DIR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;_dbg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ else }}:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;TOOL_DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;TOOL_DEBUG_DIR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;_dbg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/azure-devops/conditional-yaml/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Toggle CSS classes in Devtools</title>
      <link>https://www.brandonpugh.com/til/devtools/toggle-css-classes/</link>
      <pubDate>Fri, 13 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/toggle-css-classes/</guid>
      <description>&lt;p&gt;Today I learned that the little &lt;code&gt;.cls&lt;/code&gt; button in the Chrome devtools is a handy way to toggle classes on an element:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;toggle class screenshot&#34; loading=&#34;lazy&#34; src=&#34;toggle-css-classes.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;I imagine the trend of using utility classes was the main motivation for this feature (although apparently it&amp;rsquo;s been there for a few years and I only just figured out what it was for).&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/toggle-css-classes/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Copy git link extension</title>
      <link>https://www.brandonpugh.com/til/visual-studio/copy-git-link/</link>
      <pubDate>Wed, 11 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/visual-studio/copy-git-link/</guid>
      <description>&lt;p&gt;2025-06-16 Update: This is now &lt;a href=&#34;https://devblogs.microsoft.com/visualstudio/introducing-the-copy-git-permalink-feature-in-visual-studio-17-12/&#34;&gt;built-in to Visual Studio&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Today I learned about the &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=EtienneBAUDOUX.CopyGitLink2022&amp;amp;ssr=false#overview&#34;&gt;Copy Git Link&lt;/a&gt; extension for Visual Studio which will give you the url of currently selected lines on your git hosting provider i.e azure devops or GitHub.&lt;/p&gt;
&lt;p&gt;Especially handy for quickly pointing a teammate to a particular part of the codebase.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/visual-studio/copy-git-link/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git rerere</title>
      <link>https://www.brandonpugh.com/til/git/rerere/</link>
      <pubDate>Thu, 05 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/rerere/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve ever had to abort a rebase or merge but didn&amp;rsquo;t want to waste the work you already did resolving merge conflicts, then you should enable the git rerere option:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git global config rerere.enabled true&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It stands for Reuse Recorded Resolution, and it essentially remembers how you resolved a merge conflict and will automatically reapply if it sees it again.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://bitbucket.org/blog/resolving-conflicts-with-git-rerere&#34;&gt;Resolving conflicts with git-rerere&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/rerere/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>git-absorb</title>
      <link>https://www.brandonpugh.com/til/git/git-absorb/</link>
      <pubDate>Wed, 04 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/git-absorb/</guid>
      <description>&lt;p&gt;One of my favorite git plugins is &lt;a href=&#34;https://github.com/tummychow/git-absorb&#34;&gt;git-absorb&lt;/a&gt; (which is a port of Mercurial&amp;rsquo;s absorb).&lt;br&gt;
It basically helps you create &lt;code&gt;--fixup&lt;/code&gt; commits automatically, which you can then use an interactive rebase with autoSquash to &amp;ldquo;absorb&amp;rdquo; them into your previous commits.&lt;/p&gt;
&lt;p&gt;I tend to use it when I&amp;rsquo;ve made a bunch of small tweaks to my feature branch, especially from automated feedback from a PR bot, I&amp;rsquo;ll then stage the changes and &lt;a href=&#34;https://github.com/tummychow/git-absorb&#34;&gt;git-absorb&lt;/a&gt; will find the previous commit on my branch that also modified those same lines.&lt;/p&gt;
&lt;p&gt;I have a git alias set to run:
&lt;code&gt;git absorb --base main --force&lt;/code&gt;&lt;br&gt;
So it&amp;rsquo;ll search through all the commits on my branch whether I&amp;rsquo;ve pushed them or not.&lt;/p&gt;
&lt;p&gt;As usual Andrew Lock has the best post explaining it: (&lt;a href=&#34;https://andrewlock.net/super-charging-git-rebase-with-git-absorb/&#34;&gt;https://andrewlock.net/super-charging-git-rebase-with-git-absorb/&lt;/a&gt;)&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/git-absorb/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>push.autoSetupRemote</title>
      <link>https://www.brandonpugh.com/til/git/auto-setup-remote/</link>
      <pubDate>Tue, 03 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/auto-setup-remote/</guid>
      <description>&lt;p&gt;Today I learned about the git config setting &lt;code&gt;push.autoSetupRemote&lt;/code&gt; that was added in version 2.37.0.&lt;/p&gt;
&lt;p&gt;Like &lt;a href=&#34;https://tekin.co.uk/2020/01/git-alias-to-push-and-set-upstream-trackng-on-a-branch&#34;&gt;Tekin mentions in his post&lt;/a&gt;, I&amp;rsquo;ve had a git alias to do create my upstream branch but I still forget sometimes.
To me this seems safe to enable by default with:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git config --global --add --bool push.autoSetupRemote true&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and git will now set the upstream tracking branch for you!&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/auto-setup-remote/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use the `valueAsNumber` property of html number inputs</title>
      <link>https://www.brandonpugh.com/til/html/valueasnumber/</link>
      <pubDate>Mon, 02 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/valueasnumber/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;code&gt;valueAsNumber&lt;/code&gt; property of html number inputs.&lt;/p&gt;
&lt;p&gt;So instead of having to parse the value like: &lt;code&gt;const num = parseFloat(e.target.value)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You can do: &lt;code&gt;const num = e.target.valueAsNumber&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;For example in react:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-jsx&#34; data-lang=&#34;jsx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;input&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;number&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;onChange&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// ✅
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;valueAsNumber&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;setNumber&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;https://www.builder.io/blog/numbers-and-dates&#34;&gt;Work With Number and Date Inputs in JavaScript&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/valueasnumber/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Format a paragraph</title>
      <link>https://www.brandonpugh.com/til/vim/format-paragraph-hard-wrap/</link>
      <pubDate>Sun, 01 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/format-paragraph-hard-wrap/</guid>
      <description>&lt;p&gt;In vim you can &lt;a href=&#34;https://vim.fandom.com/wiki/Automatic_formatting_of_paragraphs&#34;&gt;format a paragraph&lt;/a&gt; of prose text with &lt;code&gt;gq&lt;/code&gt;.
This basically will hard-wrap the lines to the configured &lt;code&gt;textwidth&lt;/code&gt; for the filetype.&lt;/p&gt;
&lt;p&gt;I use this all the time when writing git commit messages so the body of the message has the &lt;a href=&#34;https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html&#34;&gt;recommended&lt;/a&gt; max line length of 72.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/format-paragraph-hard-wrap/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Preserve case with find and replace</title>
      <link>https://www.brandonpugh.com/til/vscode/find-replace-preserve-case/</link>
      <pubDate>Fri, 29 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/find-replace-preserve-case/</guid>
      <description>&lt;p&gt;Today I learned that vscode has an option to &lt;a href=&#34;https://code.visualstudio.com/updates/v1_37#_preserve-case-in-find-and-replace&#34;&gt;preserve case with find and replace&lt;/a&gt; (I somehow never noticed the &amp;ldquo;AB&amp;rdquo; button before).
I&amp;rsquo;ve always wanted this when having to rename an entity in a file with instances both capitalized and lowercase.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;preserve case screenshot&#34; loading=&#34;lazy&#34; src=&#34;./preserve-case.gif&#34;&gt;&lt;/p&gt;
&lt;p&gt;I actually discovered this because I saw that this feature was just added to the latest &lt;a href=&#34;https://devblogs.microsoft.com/visualstudio/keep-your-casing-with-case-preserving-find-and-replace/&#34;&gt;Visual Studio 2022 preview&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And for vim users, there&amp;rsquo;s &lt;a href=&#34;https://github.com/tpope/vim-abolish&#34;&gt;Vim Abolish&lt;/a&gt; 😁&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/find-replace-preserve-case/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>SVG sprites</title>
      <link>https://www.brandonpugh.com/til/html/svg-sprites/</link>
      <pubDate>Thu, 28 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/svg-sprites/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt; element and how you can use it to create &lt;a href=&#34;https://benadam.me/thoughts/react-svg-sprites/&#34;&gt;&lt;em&gt;SVG&lt;/em&gt; sprites&lt;/a&gt;.
It turns out that my preferred way of working with svgs in react by embedding them in the components, &lt;a href=&#34;https://kurtextrem.de/posts/svg-in-js&#34;&gt;is not great for performance&lt;/a&gt; or bundle size.
But as &lt;a href=&#34;https://benadam.me/thoughts/react-svg-sprites/&#34;&gt;Ben Adam&amp;rsquo;s post shows&lt;/a&gt;, it looks like inline svgs using sprites gives you the best performance to development experience tradoff.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/svg-sprites/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>One-time code autocomplete</title>
      <link>https://www.brandonpugh.com/til/html/one-time-code-autocomplete/</link>
      <pubDate>Wed, 27 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/one-time-code-autocomplete/</guid>
      <description>&lt;p&gt;I just discovered that there is a &lt;code&gt;autocomplete=&amp;quot;one-time-code&amp;quot;&lt;/code&gt; value you can use on mobile devices where the operating system will autopopulate the field with a code that the user receives via SMS.
I haven&amp;rsquo;t had a chance to test it out but it seems pretty cool and I wish every banking site would just add this one html attribute (since they seem unable to add any MFA option other than SMS).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://web.dev/articles/sms-otp-form#autocompleteone-time-code&#34;&gt;SMS OTP code&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/one-time-code-autocomplete/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>--update-refs won&#39;t update a ref if it&#39;s currently checked out in a working directory</title>
      <link>https://www.brandonpugh.com/til/git/update-refs-working-directory/</link>
      <pubDate>Mon, 25 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/update-refs-working-directory/</guid>
      <description>&lt;p&gt;Today I learned that if you&amp;rsquo;re using the fairly new &lt;code&gt;--update-refs&lt;/code&gt; feature of git to update multiple refs during a rebase, git won&amp;rsquo;t update a ref if it&amp;rsquo;s currently checked out in another working directory for that repo.&lt;/p&gt;
&lt;p&gt;This makes sense but git currently doesn&amp;rsquo;t give you any feedback that it wasn&amp;rsquo;t updated or why. It wasn&amp;rsquo;t until I tried to manually update it with a &lt;code&gt;git branch --force&lt;/code&gt; that it told me the issue:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fatal: cannot force update the branch &#39;feature-1&#39; checked out at &#39;/projects/my-other-branch&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re not familiar with either of these features I highly recommend looking into them.
Andrew Lock has excellet write-ups on them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://andrewlock.net/working-on-two-git-branches-at-once-with-git-worktree/&#34;&gt;Working on two git branches at once with git worktree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://andrewlock.net/working-with-stacked-branches-in-git-is-easier-with-update-refs/&#34;&gt;Working with stacked branches in Git is easier with &amp;ndash;update-refs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/update-refs-working-directory/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Highlight text in markdown</title>
      <link>https://www.brandonpugh.com/til/azure-devops/markdown-highlight/</link>
      <pubDate>Fri, 22 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/azure-devops/markdown-highlight/</guid>
      <description>&lt;p&gt;I just learned that you can highlight text in PR descriptions and comments on Azure devops by using the &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; element in your markdown:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;mark&amp;gt;Notice this!&amp;lt;/mark&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of highlighted text on azure devops&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/azure-devops/markdown-highlight-screenshot.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t think I was even aware of the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark&#34;&gt;&lt;code&gt;mark&lt;/code&gt; html element&lt;/a&gt; even though it&amp;rsquo;s been around for a while now.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/azure-devops/markdown-highlight/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Specify timestamp in Google Drive video URL</title>
      <link>https://www.brandonpugh.com/til/google/video-timestamp-query-param/</link>
      <pubDate>Tue, 19 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/google/video-timestamp-query-param/</guid>
      <description>&lt;p&gt;Today I learned that Google Drive uses the same video player as YouTube so if you want to link to a specific timestamp in a video you can append a URL parameter like &lt;code&gt;t=&amp;lt;number of seconds&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So to share a link to a video and have it start playing at 10:44, the URL will look like &lt;code&gt;/view?t=644&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A colleague also pointed out that you don&amp;rsquo;t have to calculate the timestamp in seconds — the &lt;code&gt;t&lt;/code&gt; parameter accepts a shorthand like so &lt;code&gt;t=10m44s&lt;/code&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/google/video-timestamp-query-param/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Disabling browser autofill in a form</title>
      <link>https://www.brandonpugh.com/til/html/disable-autocomplete/</link>
      <pubDate>Fri, 15 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/disable-autocomplete/</guid>
      <description>&lt;p&gt;Today I learned that &lt;code&gt;autocomplete=&amp;quot;off&amp;quot;&lt;/code&gt; tends to be completely ignored by browsers these days because they seem to have the attitude that websites don&amp;rsquo;t use it correctly.&lt;/p&gt;
&lt;p&gt;Apparently the best way to prevent a browser from trying to autofill a field is to tell the browser it&amp;rsquo;s not the field it thinks it is with something like &lt;code&gt;autocomplete=&amp;quot;something-else&amp;quot;&lt;/code&gt;.
If it&amp;rsquo;s anything the browser doesn&amp;rsquo;t recognize it won&amp;rsquo;t try to fill it.
It looks like &lt;code&gt;autocomplete=&amp;quot;new-password&amp;quot;&lt;/code&gt; is one people tend to use especially for any &lt;code&gt;type=&amp;quot;password&amp;quot;&lt;/code&gt; fields that aren&amp;rsquo;t actually meant to be a user&amp;rsquo;s login password.
See this &lt;a href=&#34;https://stackoverflow.com/questions/15738259/disabling-chrome-autofill&#34;&gt;StackOverflow question&lt;/a&gt; for more discussion.&lt;/p&gt;
&lt;p&gt;Likewise if you want to give the browser hints about what it should​​​​​​​ try to suggest you can use one of the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#values&#34;&gt;recognized values&lt;/a&gt; like &lt;code&gt;address-line1&lt;/code&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/disable-autocomplete/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>CSS Nesting</title>
      <link>https://www.brandonpugh.com/til/css/css-nesting/</link>
      <pubDate>Thu, 14 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/css-nesting/</guid>
      <description>&lt;p&gt;Today I learned that as of last month all modern browsers support &lt;a href=&#34;https://developer.chrome.com/articles/css-nesting/&#34;&gt;css nesting&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;So instead of having to define styles like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;header&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;header&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;font-size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;header&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;hover&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;green&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;you can instead do:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;header&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;err&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;font-size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;span&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;err&#34;&gt;&amp;amp;:hover&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;green&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;err&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This was the last feature of Sass that I used regularly that was missing from native CSS (&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties&#34;&gt;CSS variables&lt;/a&gt; being the first big one that caused me to drop pulling sass into projects).&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/css-nesting/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Mock service worker</title>
      <link>https://www.brandonpugh.com/til/javascript/mock-service-worker/</link>
      <pubDate>Wed, 13 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/mock-service-worker/</guid>
      <description>&lt;p&gt;I recently discovered &lt;a href=&#34;https://mswjs.io/&#34;&gt;Mock Service Worker&lt;/a&gt;, a clever javascript utility that let&amp;rsquo;s you mock your API by intercepting network requests.
I&amp;rsquo;ve started using it in my frontend tests after reading Kent&amp;rsquo;s article &lt;a href=&#34;https://kentcdodds.com/blog/stop-mocking-fetch&#34;&gt;Stop Mocking Fetch&lt;/a&gt; and it&amp;rsquo;s a nice way to test a component is handling network requests appropriately without actually hitting an API.
The novel aspect is that it can install itself as a service worker (which can intercept network requests for caching) in your app during development and reuse the same mock requests that you&amp;rsquo;ve setup during testing.
Handy for when the backend isn&amp;rsquo;t ready or you don&amp;rsquo;t want to take the time to get the app in the correct state to test a UI change.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/mock-service-worker/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Dev containers</title>
      <link>https://www.brandonpugh.com/til/vscode/devcontainers/</link>
      <pubDate>Mon, 11 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/devcontainers/</guid>
      <description>&lt;p&gt;Today I learned that &lt;a href=&#34;https://containers.dev/&#34;&gt;dev containers&lt;/a&gt; are an actual spec.
I&amp;rsquo;d been hearing the term more lately but I thought it was a general term for containers used for local development but it&amp;rsquo;s actually an open spec for configuring an entire development environment within a container and it&amp;rsquo;s what you use to configure a &lt;a href=&#34;https://github.com/features/codespaces&#34;&gt;github codespace&lt;/a&gt; for a repo.
But the cool thing is you can use the vscode &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers&#34;&gt;Dev containers extension&lt;/a&gt; and vscode will reopen in a docker container with all the dependencies, extensions, and configuration specified in a &lt;a href=&#34;https://containers.dev/implementors/spec/#devcontainerjson&#34;&gt;devcontainers.json&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For example, if you want to experiment with a new programming language, you can quickly launch one of the sample containers (type &amp;ldquo;try&amp;rdquo; from the command palette) and have an environment ready to go (after docker downloads the image).&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;sample container selection screenshot&#34; loading=&#34;lazy&#34; src=&#34;devcontainers.png&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/devcontainers/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>CSS accent-color property</title>
      <link>https://www.brandonpugh.com/til/css/accent-color/</link>
      <pubDate>Thu, 07 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/accent-color/</guid>
      <description>&lt;p&gt;Today I learned that browsers now support an &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/accent-color&#34;&gt;accent-color&lt;/a&gt; property on some form inputs for customizing their color.
This is especially nice for checkboxes and radio buttons because now I no longer need any workarounds I&amp;rsquo;ve used in the past to make a decent-looking checkbox.
It will also ensure that it&amp;rsquo;s accessible by automatically adjusting the color of the check to an appropriate contrast:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;checkbox&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;yellow&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;checked&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;checkbox&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;purple&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;checked&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;block&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;purple&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;accent-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;rebeccapurple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;yellow&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;accent-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;yellow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img alt=&#34;checkboxes-screenshot&#34; loading=&#34;lazy&#34; src=&#34;accent-color.png&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/accent-color/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Delta pager for Git</title>
      <link>https://www.brandonpugh.com/til/git/delta-pager/</link>
      <pubDate>Tue, 05 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/delta-pager/</guid>
      <description>&lt;p&gt;Today I learned that you can configure git to use a different diff viewer when displaying diffs from the command line.
You do this by setting the &lt;code&gt;pager&lt;/code&gt; config &lt;code&gt;git config --global core.pager delta&lt;/code&gt; and &lt;a href=&#34;https://github.com/dandavison/delta&#34;&gt;delta&lt;/a&gt; is a cool one written in Rust that can even display line numbers and syntax highlighting.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git show&lt;/code&gt; produces:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of delta git show output&#34; loading=&#34;lazy&#34; src=&#34;delta-pager.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Relatedly, it uses the same themes as &lt;a href=&#34;https://github.com/sharkdp/bat/&#34;&gt;bat&lt;/a&gt; which is a &lt;code&gt;cat&lt;/code&gt; command line replacement with syntax highlighting that is pretty nice.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/delta-pager/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Null values in javascript interpolated strings</title>
      <link>https://www.brandonpugh.com/til/javascript/string-interpolation-null/</link>
      <pubDate>Fri, 01 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/string-interpolation-null/</guid>
      <description>&lt;p&gt;Today I learned about a key difference between how javascript handles null values in interpolated strings compared to a language like C#&lt;/p&gt;
&lt;p&gt;In C#:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;param1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queryString&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;$&amp;#34;param1={param1}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// =&amp;gt; param1=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Javascript&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;param1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;queryString&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`param1=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;param1&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// =&amp;gt; param1=null
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the latter is probably not what you want since your api will likely set param1 to a string value of &amp;ldquo;null&amp;rdquo;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/string-interpolation-null/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Object.fromEntries</title>
      <link>https://www.brandonpugh.com/til/javascript/from-entries/</link>
      <pubDate>Wed, 30 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/from-entries/</guid>
      <description>&lt;p&gt;Today I learned about &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries&#34;&gt;Object.fromEntries()&lt;/a&gt; in javascript which essentially lets you convert a list of key/value pairs into an object (this is the same as the lodash function &lt;code&gt;fromPairs&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;This came in handy when I needed to convert a list of entities into a lookup object like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fromEntries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;users&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isSelected&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// =&amp;gt; { &amp;#39;1&amp;#39;: true, &amp;#39;2&amp;#39;: false, &amp;#39;3&amp;#39;: false }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/from-entries/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Emulate page focus</title>
      <link>https://www.brandonpugh.com/til/devtools/emulate-focused-page/</link>
      <pubDate>Mon, 28 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/emulate-focused-page/</guid>
      <description>&lt;p&gt;Today I learned about a devtools feature that helped me debug the styling of an element that would disappear when the input element lost focus which happens when you click over to the devtools.&lt;/p&gt;
&lt;p&gt;If you press &lt;code&gt;ctrl+shift+p&lt;/code&gt; to open the command palette in DevTools, and type &amp;ldquo;focus&amp;rdquo;, you&amp;rsquo;ll see a command to &amp;ldquo;Emulate a focused page&amp;rdquo; which will leave the focus on the element in the page even when you click into the DevTools.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://levelup.gitconnected.com/different-ways-to-inspect-disappearing-elements-on-a-browser-5df42888b7cf&#34;&gt;This post&lt;/a&gt; shows several other techniques you could potentially use but I found this option to work best for my scenario.&lt;/p&gt;
&lt;p&gt;My favorite technique is this clever javascript snippet you can run from the console:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;setTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;debugger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/emulate-focused-page/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Ternary in C# string interpolation</title>
      <link>https://www.brandonpugh.com/til/csharp/string-interpolation/</link>
      <pubDate>Wed, 23 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/csharp/string-interpolation/</guid>
      <description>&lt;p&gt;Today I learned you can have ternary expressions inside of interpolated strings, you just need to wrap it in parenthesis:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$&amp;quot;{timeSpan.Hours} hour{(timeSpan.Hours &amp;gt; 1 ? &amp;quot;s&amp;quot; : &amp;quot;&amp;quot;)} ago&amp;quot;&lt;/code&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/csharp/string-interpolation/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Pretty Typescript errors Vscode extension</title>
      <link>https://www.brandonpugh.com/til/typescript/error-extension/</link>
      <pubDate>Mon, 21 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/typescript/error-extension/</guid>
      <description>&lt;p&gt;I recently discovered the &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=yoavbls.pretty-ts-errors&#34;&gt;Pretty Typescript errors&lt;/a&gt; Vscode extension that makes complicated Typescript errors much more readable in Vscode&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;tooltip comparison screenshot&#34; loading=&#34;lazy&#34; src=&#34;pretty-typescript-errors.png&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/typescript/error-extension/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Ignore commits in Git Blame with --ignore-revs-file</title>
      <link>https://www.brandonpugh.com/til/git/ignore-revs-file/</link>
      <pubDate>Thu, 17 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/ignore-revs-file/</guid>
      <description>&lt;p&gt;Today I learned that you can ignore commits in Git blame on Github with a &lt;code&gt;.git-blame-ignore-revs&lt;/code&gt; file in the root of your repo!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d known about the &lt;code&gt;git config blame.ignoreRevsFile&lt;/code&gt; config option where you can point it to a file with a list of commit IDs to ignore which is especially useful for those annoying commits in a repo where whitespace was cleaned up or every tab in the codebase was replaced with spaces.
You have to run the &lt;a href=&#34;https://www.stefanjudis.com/today-i-learned/how-to-exclude-commits-from-git-blame/&#34;&gt;config command locally&lt;/a&gt; but now apparently &lt;a href=&#34;https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view&#34;&gt;Github does it automatically&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also learned you can include comments in the file like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Run this command to always ignore formatting commits in `git blame`
# git config blame.ignoreRevsFile .git-blame-ignore-revs

# Changed everything to tabs
a926bba49c89a5b882cd298be3af2570b1e6252c

# Fixed all the formatting errors
5e78fdc6eac01e4e730046dc2811fbb78157a154
&lt;/code&gt;&lt;/pre&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/ignore-revs-file/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git branch --force</title>
      <link>https://www.brandonpugh.com/til/git/branch-force/</link>
      <pubDate>Wed, 16 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/branch-force/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;a href=&#34;https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---force&#34;&gt;&lt;code&gt;--force&lt;/code&gt;&lt;/a&gt; parameter of &lt;code&gt;git branch&lt;/code&gt; which will take an existing branch and point it to a different commit.
This is another handy alternative to &lt;code&gt;git reset --hard&lt;/code&gt; for some common scenarios.&lt;/p&gt;
&lt;p&gt;For example, if I forgot to create a new feature branch and accidentally made some commits onto &lt;code&gt;main&lt;/code&gt;, I can run the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git checkout -b new-branch &lt;span class=&#34;c1&#34;&gt;# create the new branch and switch to it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git branch --force main origin/main &lt;span class=&#34;c1&#34;&gt;# fix main back to what it should be&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;vs what I would do before:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git branch new-branch
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git reset --hard origin/main
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git checkout new-branch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which is one less command, but even better the contents of my working directory don&amp;rsquo;t have to change at all!&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/branch-force/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Find all CSS changes in Chrome DevTools</title>
      <link>https://www.brandonpugh.com/til/devtools/css-changes/</link>
      <pubDate>Tue, 15 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/css-changes/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;a href=&#34;https://developer.chrome.com/docs/devtools/changes/&#34;&gt;Changes tab&lt;/a&gt; in Chrome devtools.&lt;/p&gt;
&lt;p&gt;When you&amp;rsquo;re tweaking CSS styles in Chrome DevTools, you can see all the changes you&amp;rsquo;ve made by clicking the &amp;ldquo;Changes&amp;rdquo; tab in the bottom &amp;ldquo;drawer&amp;rdquo; in DevTools.
It&amp;rsquo;s especially nice because you can then copy the changes to your clipboard and paste them into your actual source file.
You can open it from the command palette (&lt;code&gt;ctrl+shift+p&lt;/code&gt;) and typing &amp;ldquo;show changes&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;One caveat I&amp;rsquo;ve noticed is that it doesn&amp;rsquo;t show styles you&amp;rsquo;ve added directly to an element as an inline style.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/css-changes/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Javascript Array.prototype.with()</title>
      <link>https://www.brandonpugh.com/til/javascript/array-with/</link>
      <pubDate>Fri, 11 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/array-with/</guid>
      <description>&lt;p&gt;I just discovered the &lt;code&gt;with()&lt;/code&gt; method which takes an index value and a value to insert at that index and returns a new array with the value inserted at the index.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;arr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;newArr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;arr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;newArr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// [1, 2, &amp;#39;a&amp;#39;, 4, 5]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You could do this before with something like &lt;code&gt;arr[2] = &#39;a&#39;&lt;/code&gt; but that would modify the original array.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;with()&lt;/code&gt; method became widely supported in 2021.&lt;/p&gt;
&lt;p&gt;Read more about the &lt;code&gt;with()&lt;/code&gt; method and alternatives in &lt;a href=&#34;https://www.stefanjudis.com/snippets/copy-array-and-replace-one-element-at-index-javascript/&#34;&gt;Stefan Judis&amp;rsquo; post&lt;/a&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/array-with/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Awesome AZD templates</title>
      <link>https://www.brandonpugh.com/til/azure/awesome-azd/</link>
      <pubDate>Thu, 10 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/azure/awesome-azd/</guid>
      <description>&lt;p&gt;Today I discovered the &lt;a href=&#34;https://azure.github.io/awesome-azd/&#34;&gt;Awesome AZD templates&lt;/a&gt; site which is essentially a curated gallery of a bunch of templates for deploying to Azure with the new &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/overview?tabs=nodejs&#34;&gt;Azure developer cli&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are even several for integrating with ChatGPT like &lt;a href=&#34;https://github.com/Azure-Samples/azure-search-openai-demo-csharp/&#34;&gt;ChatGPT + Enterprise Data with Azure OpenAI and Cognitive Search&lt;/a&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/azure/awesome-azd/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git reset --keep</title>
      <link>https://www.brandonpugh.com/til/git/reset-keep/</link>
      <pubDate>Wed, 09 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/reset-keep/</guid>
      <description>&lt;p&gt;I just learned that &lt;code&gt;git reset&lt;/code&gt; has a &lt;code&gt;--keep&lt;/code&gt; parameter.&lt;/p&gt;
&lt;p&gt;This works the same as &lt;code&gt;--hard&lt;/code&gt; except that it won&amp;rsquo;t discard any uncommitted changes.
It&amp;rsquo;s meant to be used when we want to remove some of the last commits in the current branch but if there could be conflicts between the changes in the commits we want to remove and our uncommitted changes, then the reset is blocked.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d been using &lt;code&gt;git reset --hard&lt;/code&gt; and just double checking I didn&amp;rsquo;t have anything uncommitted but I&amp;rsquo;ll be defaulting to &lt;code&gt;--keep&lt;/code&gt; except if I&amp;rsquo;m intentionally trying to clear out my changes.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/reset-keep/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Comment styles in React</title>
      <link>https://www.brandonpugh.com/til/react/single-line-comments/</link>
      <pubDate>Tue, 08 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/react/single-line-comments/</guid>
      <description>&lt;p&gt;I recently learned that there are actually several ways to add &lt;a href=&#34;https://dmitripavlutin.com/react-comments/&#34;&gt;comments in JSX in React&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I had known about the &lt;code&gt;{/* comment */}&lt;/code&gt; syntax but didn&amp;rsquo;t realize you could use &lt;code&gt;//&lt;/code&gt; &lt;em&gt;within&lt;/em&gt; a jsx element:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-jsx&#34; data-lang=&#34;jsx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;MyComponent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;Hello&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;na&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Hello, World!&amp;#34;&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;//&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;prop&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;requires&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/react/single-line-comments/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git pickaxe</title>
      <link>https://www.brandonpugh.com/til/git/git-pickaxe/</link>
      <pubDate>Mon, 07 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/git-pickaxe/</guid>
      <description>&lt;p&gt;You can search through git history not only by the text of a commit message but by the &lt;em&gt;contents of the diff&lt;/em&gt; of commits.
This is commonly referred to as the &lt;a href=&#34;http://www.philandstuff.com/2014/02/09/git-pickaxe.html&#34;&gt;git pickaxe&lt;/a&gt; and you invoke it with the &lt;code&gt;-S&lt;/code&gt; parameter to &lt;code&gt;git log&lt;/code&gt; i.e. &lt;code&gt;git log -S &#39;public void SomeMethod&lt;/code&gt; and you&amp;rsquo;ll get every commit that touched that method signature or even one that &lt;em&gt;deleted&lt;/em&gt; it.&lt;/p&gt;
&lt;p&gt;Some git clients will expose this as an option in a search field but if that fails the git cli lets you include additional filters like author or file path or even use regex with the &lt;code&gt;--pickaxe-regex&lt;/code&gt; switch.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.philandstuff.com/2014/02/09/git-pickaxe.html&#34;&gt;See an example&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/git-pickaxe/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Bram Moolenaar has passed</title>
      <link>https://www.brandonpugh.com/til/vim/vim-boss-bram/</link>
      <pubDate>Sat, 05 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vim/vim-boss-bram/</guid>
      <description>&lt;p&gt;I just found out &lt;a href=&#34;https://news.ycombinator.com/item?id=37011324&#34;&gt;about the passing&lt;/a&gt; of Bram Moolenaar, the core maintainer of Vim for the last 30 years 😞&lt;/p&gt;
&lt;p&gt;I like what a commenter posted:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vim has soul. It is that chisel you inherited from your grandpa that you keep using. It fits well in your grip and is comfortable, even though it lacks the soft rubber that the new ones in the store have. It&amp;rsquo;s a tool with its own history.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Vim was the first real editor I used. I learned it on the CS department shared Unix server by following the instructions on a paper handout our TA gave us&amp;hellip; and ever since I haven&amp;rsquo;t been able to type in anything without &lt;code&gt;hjkl&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://neovim.io/news/2023/08&#34;&gt;Vim Boss&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vim/vim-boss-bram/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Multi-line string in YAML</title>
      <link>https://www.brandonpugh.com/til/yaml/multiline-strings/</link>
      <pubDate>Fri, 04 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/yaml/multiline-strings/</guid>
      <description>&lt;p&gt;It turns out there are actually several different ways to handle multiline strings in YAML.
I had noticed varying forms of the syntax but didn&amp;rsquo;t realize they process the strings differently.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://yaml-multiline.info/&#34;&gt;YAML multiline strings&lt;/a&gt; is a handy site with interactive examples of the different forms.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/yaml/multiline-strings/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Paste a URL as a markdown link</title>
      <link>https://www.brandonpugh.com/til/vscode/paste-markdown-url/</link>
      <pubDate>Thu, 03 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/paste-markdown-url/</guid>
      <description>&lt;p&gt;Today I learned that the latest version of VS code added a smart option to detect when you&amp;rsquo;re pasting a URL and automatically paste it as a markdown link in markdown files.&lt;/p&gt;
&lt;p&gt;You can enable it by setting the &lt;code&gt;markdown.editor.pasteUrlAsFormattedLink&lt;/code&gt; setting to &lt;code&gt;smart&lt;/code&gt; or &lt;code&gt;always&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;paste url screenshot&#34; loading=&#34;lazy&#34; src=&#34;./url-paste-vscode.gif&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://code.visualstudio.com/updates/v1_81#_markdown-paste-urls-as-formatted-links&#34;&gt;See the release notes.&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/paste-markdown-url/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>The C4 model for visualizing software architecture</title>
      <link>https://www.brandonpugh.com/til/documentation/c4-model/</link>
      <pubDate>Wed, 02 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/documentation/c4-model/</guid>
      <description>&lt;p&gt;Today I learned about the &lt;a href=&#34;https://c4model.com/&#34;&gt;C4 model&lt;/a&gt; for visualizing software architecture.
It looks like a nice framework for thinking hierarchically about the architecture of a system and how best to go about conveying it visually.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/documentation/c4-model/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Nominal types in Typescript</title>
      <link>https://www.brandonpugh.com/til/typescript/nominal-types/</link>
      <pubDate>Tue, 01 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/typescript/nominal-types/</guid>
      <description>&lt;p&gt;Today I learned about a pattern in Typescript called &amp;ldquo;Branded Types&amp;rdquo; which lets you create &amp;ldquo;nominal&amp;rdquo; types.&lt;/p&gt;
&lt;p&gt;Typescript&amp;rsquo;s type system is structural which is incredibly flexible and powerful when working with javascript patterns, but occasionally you want to add some extra strictness where even if the shape of the data is the same, you&amp;rsquo;ll get a type error if the &lt;em&gt;name&lt;/em&gt; of the types don&amp;rsquo;t match (like in C# which is a &lt;em&gt;nominal&lt;/em&gt; type system).&lt;/p&gt;
&lt;p&gt;A simple example looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;branded type example code&#34; loading=&#34;lazy&#34; src=&#34;./branded-type-example.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Read more here: &lt;a href=&#34;https://egghead.io/blog/using-branded-types-in-typescript&#34;&gt;https://egghead.io/blog/using-branded-types-in-typescript&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/typescript/nominal-types/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>You can save window layouts in Visual Studio</title>
      <link>https://www.brandonpugh.com/til/visual-studio/save-window-layout/</link>
      <pubDate>Mon, 31 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/visual-studio/save-window-layout/</guid>
      <description>&lt;p&gt;If you go to &lt;code&gt;Window &amp;gt; Save Window Layout&lt;/code&gt;, it&amp;rsquo;ll &lt;a href=&#34;https://learn.microsoft.com/en-us/visualstudio/ide/customizing-window-layouts-in-visual-studio?view=vs-2022#create-and-save-custom-layouts&#34;&gt;save your current window layout&lt;/a&gt; in Visual Studio.
For example, when I have to go from my monitor setup to just my laptop, I tend to set the solution explorer to auto-hide and make the Test Explorer smaller.&lt;/p&gt;
&lt;p&gt;Now I can do it with just a keyboard shortcut!&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/visual-studio/save-window-layout/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>You can easily wrap text with HTML tags</title>
      <link>https://www.brandonpugh.com/til/vscode/wrap-text-html/</link>
      <pubDate>Thu, 27 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/wrap-text-html/</guid>
      <description>&lt;p&gt;Using the builtin &lt;a href=&#34;https://code.visualstudio.com/docs/editor/emmet&#34;&gt;Emmet&lt;/a&gt; functionality, you select any arbitrary text or HTML and wrap it with new markup by executing the command &lt;code&gt;Emmet: Wrap with Abbreviation&lt;/code&gt; and typing an Emmet abbreviation.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to be using this all the time now!&lt;/p&gt;
&lt;p&gt;It even understands JSX so it&amp;rsquo;ll output &lt;code&gt;className&lt;/code&gt; if you specify a css class.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/wrap-text-html/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Azure Data Studio can display nicely formatted JSON data</title>
      <link>https://www.brandonpugh.com/til/azure-data-studio/json-column/</link>
      <pubDate>Wed, 26 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/azure-data-studio/json-column/</guid>
      <description>&lt;p&gt;&lt;em&gt;Update: Microsoft is &lt;a href=&#34;https://learn.microsoft.com/en-us/azure-data-studio/whats-happening-azure-data-studio?tabs=dev&#34;&gt;retiring Azure Data Studio&lt;/a&gt; but this feature is also available in the &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql&#34;&gt;MSSQL extension for VS Code&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you click on a cell with json data in the results grid in &lt;a href=&#34;https://learn.microsoft.com/en-us/sql/azure-data-studio/what-is-azure-data-studio?view=sql-server-ver16&#34;&gt;Azure Data Studio&lt;/a&gt;, then it will automatically open a new tab with the json nicely formatted and syntax highlighted.
Very handy for quickly checking the data stored in some rows with just a quick &lt;code&gt;select *&lt;/code&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/azure-data-studio/json-column/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>A hidden button in an HTML form can be submitted</title>
      <link>https://www.brandonpugh.com/til/html/hidden-button-still-submits/</link>
      <pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/html/hidden-button-still-submits/</guid>
      <description>&lt;p&gt;Even if a button is hidden with &lt;code&gt;display: none&lt;/code&gt;, if it has a type of &lt;code&gt;submit&lt;/code&gt; then it will still be activated if it&amp;rsquo;s the first button in a form and a user hits enter in a form field.&lt;/p&gt;
&lt;p&gt;So it&amp;rsquo;s a good reason to always explicitly specify the type of a button since &lt;code&gt;submit&lt;/code&gt; is the default but most of the time you want &lt;code&gt;type=&amp;quot;button&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;FYI there&amp;rsquo;s an &lt;a href=&#34;https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/button-has-type.md&#34;&gt;eslint rule&lt;/a&gt; for this for react.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/html/hidden-button-still-submits/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>lazydocker</title>
      <link>https://www.brandonpugh.com/til/containers/lazydocker/</link>
      <pubDate>Mon, 24 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/containers/lazydocker/</guid>
      <description>&lt;p&gt;Today I learned about a cool terminal UI tool for managing containers called &lt;a href=&#34;https://github.com/jesseduffield/lazydocker&#34;&gt;lazydocker&lt;/a&gt;.
I&amp;rsquo;m not really working with Docker on my current project but I&amp;rsquo;m bookmarking it for later.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re a fan of &lt;a href=&#34;https://github.com/jesseduffield/lazygit&#34;&gt;lazygit&lt;/a&gt;, lazydocker is from the same author.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/containers/lazydocker/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>VS code can show the required HTML structure for a CSS selector</title>
      <link>https://www.brandonpugh.com/til/vscode/hover-css-selector/</link>
      <pubDate>Fri, 21 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/vscode/hover-css-selector/</guid>
      <description>&lt;p&gt;If you hover over a CSS selector or property, &lt;a href=&#34;https://code.visualstudio.com/docs/languages/css&#34;&gt;VS Code&lt;/a&gt; will provide an HTML snippet that&amp;rsquo;s matched by the CSS rule, and it will also show the specificity.&lt;/p&gt;
&lt;p&gt;For example, this very specific rule that&amp;rsquo;s similar to one I came across recently:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of hovering in css&#34; loading=&#34;lazy&#34; src=&#34;./hover-css-selector.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;I also had to look up the &lt;code&gt;~&lt;/code&gt; which is the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator&#34;&gt;General sibling combinator&lt;/a&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/vscode/hover-css-selector/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Sequence Diagrams</title>
      <link>https://www.brandonpugh.com/til/documentation/sequence-diagrams/</link>
      <pubDate>Thu, 20 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/documentation/sequence-diagrams/</guid>
      <description>&lt;p&gt;I learned how to correctly &lt;a href=&#34;https://www.lucidchart.com/pages/uml-sequence-diagram&#34;&gt;read sequence diagrams&lt;/a&gt;.
I came across a recent post that suggests &amp;ldquo;&lt;a href=&#34;https://www.mermaidchart.com/blog/posts/sequence-diagrams-the-good-thing-uml-brought-to-software-development&#34;&gt;Sequence diagrams are the only good thing UML brought to software development&lt;/a&gt;&amp;rdquo;.
I&amp;rsquo;d never thought they were that useful but it turns out that was because I&amp;rsquo;d been misreading them.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s probably been a few instances over the years where I&amp;rsquo;ve made a flowchart where a sequence diagram would have been better.
For example, I tend to add a high-level overview of how a request moves through our application especially since &lt;a href=&#34;https://mermaid.js.org/&#34;&gt;Mermaid.js&lt;/a&gt; makes it really easy to add to markdown documentation (&lt;a href=&#34;https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/&#34;&gt;Github and Azure DevOps&lt;/a&gt; will both render them).&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a quick example of a typical &lt;a href=&#34;https://github.com/jbogard/ContosoUniversityDotNetCore-Pages&#34;&gt;vertical slice architecture&lt;/a&gt; we would use at Headspring.
Adding this code block to a markdown file will render a sequence diagram using Mermaid:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;  sequenceDiagram
    UI-&amp;gt;&amp;gt;api: http request
    participant api as API controller
    Note over UI,api: This gets bound to a viewModel &amp;lt;br/&amp;gt;(*[Query|Command].cs)
    participant mediatr as Mediatr handler
    api-&amp;gt;&amp;gt;mediatr: Mediatr request
    mediatr-&amp;gt;&amp;gt;DB: Entity framework query
    DB--&amp;gt;&amp;gt;mediatr: DB records
    Note over mediatr: Business logic/validation
    mediatr--&amp;gt;&amp;gt;api: Response data
    Note over api,mediatr: viewModel (*[Response|Command].cs)
    api--&amp;gt;&amp;gt;UI: http response
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Rendered on Github:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;sequence diagram as rendered on github&#34; loading=&#34;lazy&#34; src=&#34;sequence-diagram.png&#34;&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/documentation/sequence-diagrams/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Press `ctrl&#43;enter` to submit a comment on Azure DevOps</title>
      <link>https://www.brandonpugh.com/til/azure-devops/submit-comment-hotkey/</link>
      <pubDate>Wed, 19 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/azure-devops/submit-comment-hotkey/</guid>
      <description>&lt;p&gt;Pressing &lt;code&gt;ctrl+enter&lt;/code&gt; in a comment field on Azure DevOps will submit the comment!
For some reason, this isn&amp;rsquo;t listed on their &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/devops/project/navigation/keyboard-shortcuts?view=azure-devops&#34;&gt;keyboard shortcuts page&lt;/a&gt; but it&amp;rsquo;s so much nicer than using the mouse or pressing &lt;code&gt;tab&lt;/code&gt; four times.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/azure-devops/submit-comment-hotkey/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Git Extensions git client</title>
      <link>https://www.brandonpugh.com/til/git/git-extensions/</link>
      <pubDate>Tue, 18 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/git-extensions/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;https://gitextensions.github.io/&#34;&gt;Git Extensions&lt;/a&gt; git client is actually pretty powerful and has a lot more features than I thought.
I&amp;rsquo;d seen others using it before but never looked into it until I saw a StackOverflow answer suggesting to use Git Extensions to view the git reflog&amp;hellip; a feature I&amp;rsquo;ve only ever seen in &lt;a href=&#34;https://www.syntevo.com/smartgit/&#34;&gt;Smartgit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Some nice features I noticed while playing with it for a bit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;View commits from the reflog in the log view (makes it really easy to recover commits)&lt;/li&gt;
&lt;li&gt;Option to view &lt;a href=&#34;https://www.davidchudzicki.com/posts/first-parent/&#34;&gt;First Parent&lt;/a&gt; only in the log view&lt;/li&gt;
&lt;li&gt;Stage individual lines&lt;/li&gt;
&lt;li&gt;Option to launch external editor for commit message&lt;/li&gt;
&lt;li&gt;The commit message window can autocomplete file names&lt;/li&gt;
&lt;li&gt;Show/Filter any number of branches in the log view&lt;/li&gt;
&lt;li&gt;Windows file explorer integration&lt;/li&gt;
&lt;li&gt;Completely free and open-source and cross-platform&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think I still prefer &lt;a href=&#34;https://www.syntevo.com/smartgit/&#34;&gt;Smartgit&lt;/a&gt; over &lt;a href=&#34;https://gitextensions.github.io/&#34;&gt;Git Extensions&lt;/a&gt; but it&amp;rsquo;s tough to recommend Smartgit since it requires a license for Commercial use so I&amp;rsquo;m always keeping an eye out for good free options to recommend to others and now Git Extensions is my new recommendation (much better than SourceTree).&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/git-extensions/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Strong typing with JSDoc and Zod</title>
      <link>https://www.brandonpugh.com/til/javascript/types-with-jsdoc/</link>
      <pubDate>Thu, 13 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/javascript/types-with-jsdoc/</guid>
      <description>&lt;p&gt;You can get pretty good type checking in Javascript with just JSDoc comments and an editor like VS code or Visual Studio.
You&amp;rsquo;ll get most of the same intellisense and warnings in your editor as you would with Typescript.&lt;/p&gt;
&lt;p&gt;Combine this with a library like &lt;a href=&#34;https://zod.dev/&#34;&gt;Zod&lt;/a&gt; which can infer validation schemas from your types and you&amp;rsquo;ll have runtime checking also!&lt;/p&gt;
&lt;p&gt;See:
&lt;a href=&#34;https://blog.jim-nielsen.com/2023/types-in-jsdoc-with-zod/&#34;&gt;https://blog.jim-nielsen.com/2023/types-in-jsdoc-with-zod/&lt;/a&gt;
&lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html&#34;&gt;https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/javascript/types-with-jsdoc/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Visual Studio 2022 can stage individual lines in git</title>
      <link>https://www.brandonpugh.com/til/visual-studio/line-staging/</link>
      <pubDate>Wed, 12 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/visual-studio/line-staging/</guid>
      <description>&lt;p&gt;Visual Studio added support for staging to commit individual chunks of changes (also known as interactive staging).
This essentially lets you commit only parts of the changes you&amp;rsquo;ve made to a file or easily undo those changes.
This is probably my most-used feature in a git gui client.&lt;/p&gt;
&lt;p&gt;One caveat, it took me a minute to figure out how to use it in VS because if you have an external diff tool configured in git then clicking to view the diff in VS will open that tool instead of the VS diff viewer.
But you can also stage lines by clicking on the margin annotations:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;margin indicators in visual studio&#34; loading=&#34;lazy&#34; src=&#34;https://www.brandonpugh.com/til/visual-studio/vs-line-staging.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bonus TIL&lt;/strong&gt;: I now know exactly what these indicators mean.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://learn.microsoft.com/en-us/visualstudio/version-control/git-line-staging?view=vs-2022&#34;&gt;https://learn.microsoft.com/en-us/visualstudio/version-control/git-line-staging?view=vs-2022&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/visual-studio/line-staging/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use the Chrome devtools recorder to automate UI testing</title>
      <link>https://www.brandonpugh.com/til/devtools/devtools-recorder/</link>
      <pubDate>Tue, 11 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/devtools/devtools-recorder/</guid>
      <description>&lt;p&gt;Chrome devtools has a pretty decent recorder feature that can record and playback your UI interactions.
It&amp;rsquo;s currently in preview but it&amp;rsquo;s been working well for me so far.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s especially handy if you have to keep repeating the same 5 steps every time you reload the page to test your code.&lt;/p&gt;
&lt;p&gt;It automatically waits for UI elements to load and it&amp;rsquo;s pretty easy to tweak the recorded steps and export as a puppeteer script: &lt;a href=&#34;https://developer.chrome.com/docs/devtools/recorder/&#34;&gt;https://developer.chrome.com/docs/devtools/recorder/&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/devtools/devtools-recorder/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Run a bash script from Powershell</title>
      <link>https://www.brandonpugh.com/til/powershell/run-bash-script/</link>
      <pubDate>Sun, 09 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/powershell/run-bash-script/</guid>
      <description>&lt;p&gt;You can execute a bash script from Powershell on Windows by typing &lt;code&gt;bash&lt;/code&gt; if you&amp;rsquo;ve enabled WSL.
For example &lt;code&gt;bash ./new-til.sh&lt;/code&gt;. Some caveats though:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make sure you use &lt;code&gt;/&lt;/code&gt; instead of &lt;code&gt;\&lt;/code&gt; in the file path&lt;/li&gt;
&lt;li&gt;Make sure the bash script was saved with unix line-endings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also make a wrapper script for scripts you regularly execute like &lt;code&gt;new-til.ps1&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;bash&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;./&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;new-til&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;sh&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$args&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you don&amp;rsquo;t or can&amp;rsquo;t enable WSL, you can use &lt;code&gt;sh.exe&lt;/code&gt; that&amp;rsquo;s optionally installed with Git for Windows.
For example &lt;code&gt;sh ./new-til.sh&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;See this &lt;a href=&#34;https://stackoverflow.com/questions/1098786/run-bash-script-from-windows-powershell&#34;&gt;StackOverflow post&lt;/a&gt; for more caveats/solutions.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/powershell/run-bash-script/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Create new files faster</title>
      <link>https://www.brandonpugh.com/til/visual-studio/quick-add/</link>
      <pubDate>Fri, 07 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/visual-studio/quick-add/</guid>
      <description>&lt;p&gt;You can use &lt;code&gt;ctrl+shift+a&lt;/code&gt; to open the new quick add dialog in VS 2022: &lt;a href=&#34;https://devblogs.microsoft.com/visualstudio/adding-new-files-just-got-a-lot-faster/&#34;&gt;https://devblogs.microsoft.com/visualstudio/adding-new-files-just-got-a-lot-faster/&lt;/a&gt;&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/visual-studio/quick-add/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Hide a table in sql server management studio</title>
      <link>https://www.brandonpugh.com/til/sql-server/system-table/</link>
      <pubDate>Thu, 06 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/sql-server/system-table/</guid>
      <description>&lt;p&gt;Apparently in sql server you can mark any table as a system table using &lt;code&gt;EXEC sys.sp_MS_marksystemobject&lt;/code&gt; and then Management studio will hide it automatically.&lt;/p&gt;
&lt;p&gt;I ran into this because the docs say that Entity Framework 6 stores its code-first migration snapshots in a table called &lt;code&gt;__MigrationHistory&lt;/code&gt; but I couldn&amp;rsquo;t find it because it&amp;rsquo;s &lt;em&gt;hidden&lt;/em&gt; since it&amp;rsquo;s marked as a system table.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/sql-server/system-table/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use ChatGPT to explain bash scripts</title>
      <link>https://www.brandonpugh.com/til/ai/chatgpt-explains/</link>
      <pubDate>Wed, 05 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/ai/chatgpt-explains/</guid>
      <description>&lt;p&gt;Today I learned that chatGPT is pretty good at explaining cryptic bash scripts and commands.
I was trying to understand exactly how a git &lt;code&gt;prepare-commit-msg&lt;/code&gt; hook was working so I asked chatGPT to &amp;ldquo;explain the following git hook to me&amp;rdquo; and it did a pretty good job.&lt;/p&gt;
&lt;p&gt;For example, it returned tidbits like:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[[ $BRANCH_NAME =~ $BRANCH_REGEX ]]&lt;/code&gt;: This conditional statement checks if the branch name matches the BRANCH_REGEX pattern.
If the branch name starts with one or more digits, this condition will be true.
and:
&lt;code&gt;sed -i.bak -e &amp;quot;1s/^#${BASH_REMATCH[1]}: //I&amp;quot; $1&lt;/code&gt;: This line uses the &lt;code&gt;sed&lt;/code&gt; command to replace the branch number (captured by the &lt;code&gt;BRANCH_REGEX&lt;/code&gt; pattern) and a colon at the beginning of the commit message with an empty string. The &lt;code&gt;I&lt;/code&gt; flag makes the replacement case-insensitive. The &lt;code&gt;-i.bak&lt;/code&gt; option creates a backup of the original commit message file with a &lt;code&gt;.bak&lt;/code&gt; extension.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Bonus TIL&lt;/em&gt;: the &lt;code&gt;BASH_REMATCH&lt;/code&gt; variable is automatically populated with the matched string in bash when using the &lt;code&gt;=~&lt;/code&gt; regex operator&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/ai/chatgpt-explains/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use a table variable to hold a list of values</title>
      <link>https://www.brandonpugh.com/til/sql-server/table-variables/</link>
      <pubDate>Tue, 04 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/sql-server/table-variables/</guid>
      <description>&lt;p&gt;You can store a &amp;ldquo;list&amp;rdquo; of values in sql with a &lt;code&gt;table&lt;/code&gt; variable.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;DECLARE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;listOfIDs&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;listOfIDs&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Transactions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;bob&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/sql-server/table-variables/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Stacking context affects z-index</title>
      <link>https://www.brandonpugh.com/til/css/stacking-context/</link>
      <pubDate>Fri, 30 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/css/stacking-context/</guid>
      <description>&lt;p&gt;In CSS, the stacking context can impact which elements display on top of each in addition to the &lt;code&gt;z-index&lt;/code&gt;. So if you end up in a situation where cranking up the &lt;code&gt;z-index&lt;/code&gt; doesn&amp;rsquo;t seem to work, the stacking context is likely the issue.
I technically learned this a while ago but completely forgot about it until I was just reminded about it by a coworker dealing with this issue.
Josh Comeau explains it well in his post on &lt;a href=&#34;https://www.joshwcomeau.com/css/stacking-contexts/&#34;&gt;stacking contexts&lt;/a&gt;.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/css/stacking-context/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>GetUnderlyingType</title>
      <link>https://www.brandonpugh.com/til/csharp/getunderlyingtype/</link>
      <pubDate>Thu, 29 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/csharp/getunderlyingtype/</guid>
      <description>&lt;p&gt;In c# &lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/api/system.nullable.getunderlyingtype?view=net-9.0&#34;&gt;&lt;code&gt;Nullable.GetUnderlyingType(type)&lt;/code&gt;&lt;/a&gt;will return &lt;code&gt;null&lt;/code&gt; if the type is &lt;em&gt;not&lt;/em&gt; &lt;code&gt;Nullable&amp;lt;T&amp;gt;&lt;/code&gt;.
For some reason this is not what I expected.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/csharp/getunderlyingtype/feed&quot;&gt;
      </description>
    </item>
    
    <item>
      <title>Use `core.hooksPath` for shared hooks</title>
      <link>https://www.brandonpugh.com/til/git/config-hookspath/</link>
      <pubDate>Wed, 28 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://www.brandonpugh.com/til/git/config-hookspath/</guid>
      <description>&lt;p&gt;Sometime around 2019, git added the &lt;a href=&#34;https://git-scm.com/docs/git-config#Documentation/git-config.txt-corehooksPath&#34;&gt;&lt;code&gt;core.hooksPath&lt;/code&gt;&lt;/a&gt; config setting to change the directory where git will look for &lt;a href=&#34;https://git-scm.com/docs/githooks&#34;&gt;hooks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is handy for commiting shared hooks into a repo so you no longer need workarounds like a script to copy them into the default &lt;code&gt;$GIT_DIR/hooks&lt;/code&gt; folder or creating symlinks or relying on tools like &lt;a href=&#34;https://typicode.github.io/husky/&#34;&gt;Husky&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://dev.to/anibalardid/how-to-check-commit-message-and-branch-name-with-git-hooks-without-any-new-installation-n34&#34;&gt;This post&lt;/a&gt; is a good example of how you can use it.&lt;/p&gt;

       &lt;hr&gt; &lt;p&gt;Thank you for keeping RSS alive. You&#39;re awesome.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;mailto:blogrss@bpugh.dev&#34;&gt;Reply by email&lt;/a&gt;&lt;/p&gt;
        &lt;img src=&quot;https://blog.bpugh.workers.dev/cdn/images?p=/til/git/config-hookspath/feed&quot;&gt;
      </description>
    </item>
    
  </channel>
</rss>