<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Kaushik Gopal on tip - Kaushik Gopal's Website</title><link>https://kau.sh/tags/tip/</link><description>Recent content - Kaushik Gopal on tip - Kaushik Gopal's Website</description><language>en-us</language><lastBuildDate>Sun, 16 Nov 2025 18:46:05 GMT</lastBuildDate><image><url>https://kau.sh///images/kg.jpeg</url><title>Kaushik Gopal on tip - Kaushik Gopal's Website</title><link>https://kau.sh/tags/tip/</link></image><atom:link href="https://kau.sh/tags/tip/feed.xml" rel="self" type="application/rss+xml"/><item><title>
Go with monthly AI subscriptions friends</title><link>https://kau.sh/blog/ai-monthly-subs/</link><description>
&lt;p&gt;Go with monthly AI subscriptions friends&lt;/p&gt;
&lt;p&gt;I can&amp;rsquo;t remember where I read this tip, but given how fast the AI lab models
move, it&amp;rsquo;s smarter to stick with a monthly plan instead of locking into an
annual one, even if the annual price looks more attractive.&lt;/p&gt;
&lt;p&gt;I hit a &lt;a href="https://developer.android.com/training/dependency-injection"&gt;DI issue&lt;/a&gt;
on Android and was too lazy to debug it myself, so I pointed two models at it.
GPT Codex gave me the cleanest, correct fix. Claude Sonnet 4.5 found a fix, but
it wasn&amp;rsquo;t idiomatic and was pretty aggressive with the changes.&lt;/p&gt;
&lt;p&gt;A month ago, I wouldn&amp;rsquo;t have bothered with anything other than the Claude models
for coding. Today, Codex clearly feels ahead. Google is
&lt;a href="https://x.com/sundarpichai/status/1989481514393121239"&gt;about&lt;/a&gt; to ship its next
Gemini model and, from what I&amp;rsquo;m hearing, it&amp;rsquo;s going to be absurdly good.&lt;/p&gt;
&lt;p&gt;In these wonderfully unstable times, monthly subscriptions are the way to go.&lt;/p&gt;</description><guid>https://kau.sh/blog/ai-monthly-subs/</guid><pubDate>Sun, 16 Nov 2025 18:46:05 GMT</pubDate></item><item><title>
How to make the iPhone Continuity Camera work properly in Chrome</title><link>https://kau.sh/blog/iphone-camera-chrome/</link><description>
&lt;p&gt;I use a pixel as my primary android phone. But as a mobile developer, I also keep an iPhone handy for those times I need to test how an app works on iOS (especially if it&amp;rsquo;s not available on Android&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;).&lt;/p&gt;
&lt;p&gt;But my iPhone doesn&amp;rsquo;t sit in a drawer unused. It doubles up as my webcam when not being used as a phone. This is possible because I use macOS for my primary desktop needs, and this wonderful feature it enables called &amp;ldquo;Continuity Camera&amp;rdquo;. I&amp;rsquo;ve removed a webcam from my setup thanks to this, and the camera actually works much better than most webcams out there today.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s one really annoying thing about this setup. It won&amp;rsquo;t be recognized in Google Meet when using a chromium browser. Searching on Reddit points out that this is a bizzarre known security requirement for chromium browsers alone.&lt;/p&gt;
&lt;p&gt;Your iPhone needs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;to be in landscape mode (so don&amp;rsquo;t have portrait lock on)&lt;/li&gt;
&lt;li&gt;have the screen turned off&lt;/li&gt;
&lt;li&gt;to be locked&lt;/li&gt;
&lt;li&gt;motionless (so won&amp;rsquo;t work if handheld)&lt;/li&gt;
&lt;li&gt;and have an unobstructed camera&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;wut 😵‍💫&lt;/p&gt;
&lt;p&gt;But works like a charm. So if you run into this issue, fix those things and it&amp;rsquo;ll all work like a charm.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;thinking about you &lt;a href="https://flighty.app/"&gt;Flighty&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/blog/iphone-camera-chrome/</guid><pubDate>Thu, 12 Dec 2024 07:00:00 GMT</pubDate></item><item><title>
Pick the right JDK for Android Studio</title><link>https://kau.sh/blog/studio-jdk/</link><description>
&lt;p&gt;If Android developers don&amp;rsquo;t setup the JDK correctly, you&amp;rsquo;ll be greeted with nasty errors like this:&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="java-lang-error.webp"
alt="error shown in Android Studio when incorrect jdk used"
loading="lazy" decoding="async"
/&gt;
&lt;figcaption&gt;
Check your module classpath error
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Cannot access &amp;#39;java.lang.constant.Constable&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;which is a supertype of &amp;#39;java.lang.Class&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Check your module classpath for missing or conflicting dependencies
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Your app might compile fine but the IDE will keep surfacing pesky errors. This is because Android developers have a variety of ways to setup the JDK for your development environment. Too many.&lt;/p&gt;
&lt;p&gt;On episode &lt;a href="https://fragmentedpodcast.com/episodes/249-java-and-the-jdk-powering-the-android-landscape-with-michael-bailey/"&gt;#249 of Fragmented&lt;/a&gt; we discussed the numerous JDK options and what they&amp;rsquo;re used for. Google now has an excellent &lt;a href="https://developer.android.com/build/jdks"&gt;developer doc&lt;/a&gt; for this.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="jdks.webp"
alt="different ways for android developer to choose a jdk"
loading="lazy" decoding="async"
/&gt;
&lt;figcaption&gt;
&lt;a class="center" href="https://developer.android.com/build/jdks"&gt;
Courtesy: Android Developer docs
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;If you don&amp;rsquo;t have time to catch up on all the valuable content above, here&amp;rsquo;s the takeaways:&lt;/p&gt;
&lt;h1 id="1-use-the-jdk-that-comes-with-android-studio"&gt;
1. Use the JDK that comes with Android Studio
&lt;a class="heading-anchor" href="#1-use-the-jdk-that-comes-with-android-studio" aria-label="Link to 1. Use the JDK that comes with Android Studio"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;JBR&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; is battle tested with Android Studio and includes enhancements for running Android Studio well. To use it as your SDK, switch your Gradle JDK to JBR:&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="jbr.webp"
alt="pick JBR"
loading="lazy" decoding="async"
/&gt;
&lt;figcaption&gt;
how to set jbr as your gradle jdk
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Do a File &amp;gt; Invalidate Caches after this…&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="invalidate-caches.webp"
alt="Famous Android Studio option - Invalidate Caches"
loading="lazy" decoding="async"
/&gt;
&lt;figcaption&gt;
mother of all fixes
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;h1 id="2-match-yourjava_home-with-the-gradle-jdk"&gt;
2. Match your&lt;code&gt;JAVA_HOME&lt;/code&gt; with the Gradle JDK
&lt;a class="heading-anchor" href="#2-match-yourjava_home-with-the-gradle-jdk" aria-label="Link to 2. Match yourJAVA_HOME with the Gradle JDK"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;The Gradle JDK from Step 1 is used to compile your app from Android Studio. If you use the command line to build your app on the other hand, the JDK from your &lt;code&gt;$JAVA_HOME&lt;/code&gt;&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt; is used.&lt;/p&gt;
&lt;p&gt;If both of these don&amp;rsquo;t match, you can have multiple gradle daemons running around. Make sure to match the two.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ~/.zshenv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export JAVA_HOME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$HOME/Applications/Android&lt;span style="color:#ae81ff"&gt;\ &lt;/span&gt;Studio.app/Contents/jbr/Contents/Home
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you&amp;rsquo;re not sure where the jbr-jdk is located:&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="jbr-path.webp"
alt="JBR path"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;This is the way.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;no seriously, it&amp;rsquo;s really good.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;JetBrains Runtime&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;…if you haven&amp;rsquo;t customized your environment too much. It&amp;rsquo;s a little more &lt;a href="https://developer.android.com/build/jdks#jdk-android-studio"&gt;involved&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/blog/studio-jdk/</guid><pubDate>Wed, 06 Mar 2024 08:00:00 GMT</pubDate></item><item><title>
letter.kau.sh – 2024 Mar</title><link>https://kau.sh/letter/3/</link><description>
&lt;figure &gt;
&lt;img src="https://kau.sh/images/content/newsletter-banner.webp"
alt="banner for letter.kau.sh"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;p&gt;Welcome to the third installment of my &lt;a href="https://kau.sh/letter/"&gt;newsletter&lt;/a&gt;. Your support as always means everything to me.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s dive in.&lt;/p&gt;
&lt;h1 id="what-im-watching-listening-reading"&gt;
What I&amp;rsquo;m watching, listening, reading
&lt;a class="heading-anchor" href="#what-im-watching-listening-reading" aria-label="Link to What I’m watching, listening, reading"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h3 id="video-you"&gt;
[video] &lt;a href="https://www.youtube.com/watch?v=mxURe-EUmAs"&gt;You&amp;rsquo;re Not Forgetful: My System for Memorizing Everything&lt;/a&gt;
&lt;a class="heading-anchor" href="#video-you" aria-label="Link to [video] You"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Most people think they have a terrible memory. I know I did. This video by a YouTuber doctor challenged me to rethink that. I haven&amp;rsquo;t noticed a change in my memory&amp;rsquo;s capacity, but I&amp;rsquo;ve learned &lt;em&gt;how&lt;/em&gt; to remember more.&lt;/p&gt;
&lt;h3 id="video-apple-tv-masters-of-the-air"&gt;
[video] &lt;a href="https://www.themoviedb.org/tv/46518-masters-of-the-air"&gt;Apple TV+ Masters of the Air&lt;/a&gt;
&lt;a class="heading-anchor" href="#video-apple-tv-masters-of-the-air" aria-label="Link to [video] Apple TV&amp;#43; Masters of the Air"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Exceptionally shot. Solid &lt;a href="https://kau.sh/blog/movie-rating-system#3-like"&gt;3.5 rating&lt;/a&gt; and worth the watch. Apple TV+ has been killing it.&lt;/p&gt;
&lt;h3 id="music-video-sample-breakdown-daft-punk---discovery"&gt;
[music video] &lt;a href="https://www.youtube.com/watch?v=5AqHSvR9bqs"&gt;Sample Breakdown: Daft Punk - Discovery&lt;/a&gt;
&lt;a class="heading-anchor" href="#music-video-sample-breakdown-daft-punk---discovery" aria-label="Link to [music video] Sample Breakdown: Daft Punk - Discovery"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Sampling is the art of reusing a portion of a sound recording in another recording. It&amp;rsquo;s had a complicated history, especially with music licensing concerns and whatnot. Young Guru (Jay-Z&amp;rsquo;s tour D.J) has a good &lt;a href="https://www.youtube.com/watch?v=nnIPWgzXvyA"&gt;video&lt;/a&gt; explaining this.&lt;/p&gt;
&lt;p&gt;But to fully appreciate sampling as an art, it&amp;rsquo;s not enough to hear the music; you have to visually &amp;ldquo;see&amp;rdquo; it. See watch Daft Punk &lt;a href="https://www.youtube.com/watch?v=5AqHSvR9bqs"&gt;do their magic&lt;/a&gt; now.&lt;/p&gt;
&lt;h3 id="audio-book-leadership-strategy-and-tactics"&gt;
[audio book] &lt;a href="https://a.co/d/8kkgYyK"&gt;Leadership Strategy and Tactics&lt;/a&gt;
&lt;a class="heading-anchor" href="#audio-book-leadership-strategy-and-tactics" aria-label="Link to [audio book] Leadership Strategy and Tactics"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve been looking for good reads on leadership and this book by an ex-Navy seal came recommended. I have qualms with the narrator&amp;rsquo;s voice but I must say this was a good book with apt analogies.&lt;/p&gt;
&lt;h1 id="tips"&gt;
Tips
&lt;a class="heading-anchor" href="#tips" aria-label="Link to Tips"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="-apple-music"&gt;
🚫 Apple Music
&lt;a class="heading-anchor" href="#-apple-music" aria-label="Link to 🚫 Apple Music"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I use bluetooth headphones with my Mac and it drives me 🦇 💩 🍌 😡 every time I hit the play/pause button and see this window:&lt;/p&gt;
&lt;figure &gt;
&lt;img src="apple-music.webp"
alt="Apple Music Start Window"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;p&gt;I don&amp;rsquo;t use Apple Music. I don&amp;rsquo;t want it to open every time. I&amp;rsquo;d love to disable it. Heck, I&amp;rsquo;d love to uninstall it altogether. Sadly, Apple doesn&amp;rsquo;t allow you to do this. No worries, &lt;a href="https://github.com/tombonez/noTunes"&gt;noTunes&lt;/a&gt; has got your back:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install --cask notunes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A minor yet significant annoyance, zapped away.&lt;/p&gt;
&lt;h2 id="new-font---commitmono"&gt;
New font - CommitMono
&lt;a class="heading-anchor" href="#new-font---commitmono" aria-label="Link to New font - CommitMono"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Readers of my blog know I&amp;rsquo;m obsessed with monospaced &lt;a href="https://kau.sh/tags/font/"&gt;fonts&lt;/a&gt;. For my daily programming, I used a custom version of &lt;a href="https://kau.sh/blog/freeze-alt-char-open-type-font/"&gt;IBM Plex Mono&lt;/a&gt; and now more often &lt;a href="https://developer.apple.com/fonts/"&gt;San Francisco Mono&lt;/a&gt; &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;. I&amp;rsquo;m weary of using SF Mono though because of &lt;a href="https://github.com/supercomputra/SF-Mono-Font/issues/3#issuecomment-529811872"&gt;Apple&amp;rsquo;s restrictive licensing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Imagine my happiness finding a new worthy contender - &lt;a href="https://commitmono.com/"&gt;CommitMono&lt;/a&gt;. I admire the Danish creator&amp;rsquo;s philosophy around it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are better ways to design than putting a big effort into making something look special. Special is generally less useful than normal, and less rewarding in the long term. Special things demand attention for the wrong reasons, interrupting potentially good atmosphere with their awkward presence.&lt;/p&gt;
&lt;p&gt;— Jasper Morrison, Super Normal Manifesto&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There&amp;rsquo;s an option to customize it and you bet I did…&lt;/p&gt;
&lt;figure &gt;
&lt;img src="commit-mono-customization.webp"
alt="Customizations for CommitMono"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;p&gt;I do wish there was an alternative version of &amp;ldquo;r&amp;rdquo; with the extender at the baseline. That would make it 🧑‍🍳 💋.&lt;/p&gt;
&lt;h1 id="signing-off"&gt;
Signing off
&lt;a class="heading-anchor" href="#signing-off" aria-label="Link to Signing off"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;This was a tough month. A few of my colleagues and friends who I deeply admire were let go. Turbulent times in tech :/.&lt;/p&gt;
&lt;p&gt;Thank you once again for your support and readership. Your &lt;a href="https://kau.sh/contact/"&gt;feedback&lt;/a&gt; is always welcome.&lt;/p&gt;
&lt;p&gt;Until the next one.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;which comes baked in with the Mac&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/letter/3/</guid><pubDate>Fri, 01 Mar 2024 08:00:00 GMT</pubDate></item><item><title>
Option ⌥ key for shortcuts vs special characters</title><link>https://kau.sh/blog/option-keyboard-shortcut-macos/</link><description>
&lt;p&gt;Ever tried using the option key (&lt;code&gt;⌥&lt;/code&gt;) with another character as a keyboard shortcut in a macOS app?&lt;/p&gt;
&lt;p&gt;For example, in &lt;a href="https://obsidian.md/"&gt;Obsidian&lt;/a&gt; I use &lt;code&gt;⌥ r&lt;/code&gt; to replace templates in the active file; or &lt;code&gt;⌥ a&lt;/code&gt; to archive completed tasks for the day.&lt;/p&gt;
&lt;p&gt;Using the &lt;em&gt;default English &amp;gt; U.S.&lt;/em&gt; keyboard (or &lt;em&gt;ABC&lt;/em&gt;) types special characters in your app like å or ® vs executing your app shortcuts. It&amp;rsquo;s frustrating.&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="kb-US-ABC.png"
alt="macOS option for keyboard input type"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;If you&amp;rsquo;re heavy keyboard shortcut or a programmer wanting to use more keyboard shortcuts in your IDE like me, you&amp;rsquo;ll derive more use from ⌥ being used as a keyboard shortcut modifier.&lt;/p&gt;
&lt;h2 id="solution-1-"&gt;
Solution 1 ✗
&lt;a class="heading-anchor" href="#solution-1-" aria-label="Link to Solution 1 ✗"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m not one to shy away from &lt;a href="https://kau.sh/blog/hacking-your-keyboard/"&gt;keyboard hacking&lt;/a&gt;. So I tried Karabiner to force remap the &lt;code&gt;⌥&lt;/code&gt; keystroke when typed with another character, sending it directly to the application. That didn&amp;rsquo;t work.&lt;/p&gt;
&lt;p&gt;I then pulled out my trusty &lt;a href="https://kau.sh/tags/maestro/"&gt;Keyboard Maestro&lt;/a&gt; which is the tool I fall back to when all else fails. Nope, macOS seems to hijack these keystrokes at a deeper level.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id="solution-2-"&gt;
Solution 2 ~
&lt;a class="heading-anchor" href="#solution-2-" aria-label="Link to Solution 2 ~"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;There&amp;rsquo;s a quicker solution&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; – pick a different keyboard. A lot of online posts specifically recommend a &amp;ldquo;Unicode Hex Input&amp;rdquo; keyboard.&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="kb-uhi.png"
alt="macOS option for keyboard input type"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;You can start using &lt;code&gt;⌥ a&lt;/code&gt; without å showing up, no sweat and the keyboard shortcuts work. The Unicode Hex Input keyboard is additionally cool cause it allows typing out unicode characters with their full code. Here&amp;rsquo;s an example: hold the &lt;code&gt;⌥&lt;/code&gt; key and type &lt;code&gt;03c0&lt;/code&gt; to see what you get.&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Problem solved? Not completely.&lt;/p&gt;
&lt;p&gt;Open a program like &lt;a href="https://ia.net/writer"&gt;iA writer&lt;/a&gt;&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt; or &lt;a href="https://arc.net/"&gt;Arc&lt;/a&gt; and try using the keyboard shortcut &lt;code&gt;⌥ ⇧ →&lt;/code&gt; or &lt;code&gt;⌥ ⇧ ←&lt;/code&gt;. These basic macOS wide shortcuts should select the next/previous word respectively. Those no longer work. Let&amp;rsquo;s see if there&amp;rsquo;s any other options in there?&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="kb-uhi-options.png"
alt="macOS option for keyboard input type"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;The selection shortcut start working in some apps but not all of them. Sigh. The search continues.&lt;/p&gt;
&lt;h2 id="solution-3-"&gt;
Solution 3 ✓
&lt;a class="heading-anchor" href="#solution-3-" aria-label="Link to Solution 3 ✓"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;After scouring forums, apple support threads, reddit etc. I finally found a solution that works.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll need to create a custom keyboard and provide it as an Input source to the Mac (as you saw in earlier screenshots). You can use a program like &lt;a href="https://github.com/sillsdev/Ukelele"&gt;Ukelele&lt;/a&gt; or this &lt;a href="https://wordherd.com/keyboards/"&gt;online tool&lt;/a&gt; that someone kindly created for free.&lt;/p&gt;
&lt;p&gt;Alternatively, &lt;a href="https://gist.github.com/kaushikgopal/8e8c6e641746afe53117c2194212a0c3"&gt;download&lt;/a&gt; the keyboard I made called &amp;ldquo;US Plain&amp;rdquo; and copy it over to your &lt;code&gt;~/Library/Keyboard Layouts&lt;/code&gt; directory. Log out of the mac and log in again. When you go to add a keyboard in the Input Sources menu, you&amp;rsquo;ll now find your keyboard under &amp;ldquo;Others&amp;rdquo;.&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="kb-USP.png"
alt="macOS option for keyboard input type"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;This solution reliably resolves all issues.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;probably redirecting control character codes differently 🤷🏽.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;one would incorrectly assume.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;π&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;my favorite macOS app for writing.&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/blog/option-keyboard-shortcut-macos/</guid><pubDate>Sun, 04 Feb 2024 08:00:00 GMT</pubDate></item><item><title>
letter.kau.sh – 2024 Feb</title><link>https://kau.sh/letter/2/</link><description>
&lt;figure &gt;
&lt;img src="https://kau.sh/images/content/newsletter-banner.webp"
alt="banner for letter.kau.sh"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;p&gt;Welcome to the second installment of my &lt;a href="https://kau.sh/letter/"&gt;newsletter&lt;/a&gt;. Your support means the world to me.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been told the key to building an audience is consistency. I&amp;rsquo;m committing to this idea by releasing my letter on the first day of each month. This way, you&amp;rsquo;ll always know when to look out for a new letter.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s dive in.&lt;/p&gt;
&lt;h1 id="what-im-watching-listening-reading"&gt;
What I&amp;rsquo;m watching, listening, reading
&lt;a class="heading-anchor" href="#what-im-watching-listening-reading" aria-label="Link to What I’m watching, listening, reading"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[podcast] &lt;a href="https://pod.link/1710609544"&gt;What Now?&lt;/a&gt; – Trevor Noah&amp;rsquo;s standup is good but he&amp;rsquo;s an even better interview host. His &lt;a href="https://youtu.be/MJ9F9ZuQIzE"&gt;&amp;ldquo;Between the Scenes&amp;rdquo;&lt;/a&gt; &lt;a href="https://www.youtube.com/watch?v=TLhJCerHFAw"&gt;segments&lt;/a&gt; are some of my favorite. His new podcast is really good so far.&lt;/li&gt;
&lt;li&gt;[tv] &lt;a href="https://www.themoviedb.org/tv/95480-slow-horses"&gt;Slow Horses&lt;/a&gt; – Just finished Season 1 and I&amp;rsquo;m giddy that there are two additional seasons waiting for me. The best feeling.&lt;/li&gt;
&lt;li&gt;[tv] &lt;a href="https://www.themoviedb.org/tv/225180-blue-eye-samurai?language=en-US"&gt;Blue Eye Samurai&lt;/a&gt; – I&amp;rsquo;ve swooned about this show before but I&amp;rsquo;ll promote it again any chance I get. It&amp;rsquo;s the best thing I watched in 2023.&lt;/li&gt;
&lt;li&gt;[video] &lt;a href="https://youtu.be/1mY5FNRh0h4"&gt;Where are U Now | Diary of a Song&lt;/a&gt; – Yes, it&amp;rsquo;s the one you&amp;rsquo;re thinking of, and yes it&amp;rsquo;s Beiber, but this video is specifically around how Diplo &amp;amp; Skrillex collaborated to &lt;em&gt;make&lt;/em&gt; the song. I&amp;rsquo;ve got a bunch of these to share, so stay tuned.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="tech-tips"&gt;
Tech Tips
&lt;a class="heading-anchor" href="#tech-tips" aria-label="Link to Tech Tips"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="making-use-of-the-tmp-directory"&gt;
Making use of the &lt;code&gt;/tmp&lt;/code&gt; directory
&lt;a class="heading-anchor" href="#making-use-of-the-tmp-directory" aria-label="Link to Making use of the /tmp directory"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="linux-file-system.webp"
alt="cheatsheet for linux file system"
height="650"
loading="lazy" decoding="async"
/&gt;
&lt;figcaption&gt;
&lt;a class="center" href="https://twitter.com/alexxubyte/status/1753457840541634626"&gt;
Courtesy: Alex Xu via Twitter
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Are you aware that Unix-based systems, like macOS, offer a &amp;ldquo;hidden&amp;rdquo; &lt;code&gt;/tmp&lt;/code&gt; directory that clears out every time you reboot?&lt;/p&gt;
&lt;p&gt;I set it as my default download location for files that are momentarily needed like downloads, screenshots, or installation packages. There&amp;rsquo;s no need for a manual cleanup of these files as your next reboot will just wipe them clean.&lt;/p&gt;
&lt;p&gt;Caveat: since this directory is &lt;em&gt;world-writable&lt;/em&gt;, other user profiles on your device can access these files.&lt;/p&gt;
&lt;h2 id="hiding-your-macos-dock"&gt;
Hiding your macOS dock
&lt;a class="heading-anchor" href="#hiding-your-macos-dock" aria-label="Link to Hiding your macOS dock"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The Dock is one of those macOS features that I never use and strangely, it can&amp;rsquo;t be disabled. Nicholas shared a &lt;a href="https://www.threads.net/@jitkoff/post/C2DII-sJXCR/"&gt;workaround&lt;/a&gt; that effectively hides it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;defaults write com.apple.dock autohide-delay -int &lt;span style="color:#ae81ff"&gt;60&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; killall Dock
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s been working like a charm.&lt;/p&gt;
&lt;h1 id="from-my-blog"&gt;
From my blog
&lt;a class="heading-anchor" href="#from-my-blog" aria-label="Link to From my blog"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h3 id="get-to-inbox-0-with-gmail"&gt;
&lt;a href="https://kau.sh/blog/inbox-0-gmail/"&gt;Get to Inbox 0 with Gmail&lt;/a&gt;
&lt;a class="heading-anchor" href="#get-to-inbox-0-with-gmail" aria-label="Link to Get to Inbox 0 with Gmail"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;I wrote this post excited to share my tips on taming an email inbox. I shared it with the author of the plugin mentioned. He was kind and gracious but told me that my post was vapid (without using those words). He&amp;rsquo;s right. I rushed that post in an excitement to get it out. I oversold with that title.&lt;/p&gt;
&lt;p&gt;This is why I love the internet and am willing to &lt;a href="https://kau.sh/blog/learning-and-looking-foolish/"&gt;look foolish&lt;/a&gt;. It means I&amp;rsquo;m learning. I&amp;rsquo;ve since been thinking about re-editing that post. The title should have just been - how &lt;em&gt;I&lt;/em&gt; use Gmail.&lt;/p&gt;
&lt;h3 id="replace-git-number-with-git-aliases"&gt;
&lt;a href="https://kau.sh/blog/git-alias/"&gt;Replace git-number with git aliases&lt;/a&gt;
&lt;a class="heading-anchor" href="#replace-git-number-with-git-aliases" aria-label="Link to Replace git-number with git aliases"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;I wanted to go on more about my &lt;a href="https://kau.sh/blog/simplify"&gt;simplify&lt;/a&gt; series and how pumped I am about a queue of posts I have in mind for this topic. But reason and restraint found me and I figured folks will find their way to it, in time.&lt;/p&gt;
&lt;p&gt;But if you&amp;rsquo;re curious… dear newsletter reader (❤️) the ones I&amp;rsquo;m thinking of: &amp;ldquo;How I Obsidian&amp;rdquo;, &amp;ldquo;iTerm → Terminal &amp;amp; sane dotfiles&amp;rdquo;, &amp;ldquo;Fish → Zsh&amp;rdquo;, &amp;ldquo;VSCode + NeoVim → Jetbrains&amp;rdquo;, &amp;ldquo;KeyboardMaestro + Alfred + Pastebot + WorldClock widget + … → Raycast&amp;rdquo;&lt;/p&gt;
&lt;p&gt;If there&amp;rsquo;s one that you&amp;rsquo;re eager to read, &lt;a href="https://kau.sh/contact/"&gt;let me know&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id="musings"&gt;
Musings
&lt;a class="heading-anchor" href="#musings" aria-label="Link to Musings"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="programming-for-good"&gt;
Programming for good
&lt;a class="heading-anchor" href="#programming-for-good" aria-label="Link to Programming for good"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As a programmer, I&amp;rsquo;m always looking for opportunities to apply my skills to benefit society and perform my civic duty. The opportunities are there…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The San Francisco subway system still runs on &lt;a href="https://sfstandard.com/transportation/sfs-market-street-subway-runs-on-reagan-era-floppy-disks/"&gt;5 1/4-inch floppies&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;By way of &lt;a href="https://kottke.org/23/12/52-interesting-things-i-learned-2023"&gt;Jason Kotke&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;SF has the best software engineers in the world and they&amp;rsquo;re riding the very Munis that run on 5¼ floppies, all around San Francisco. Yet, there isn&amp;rsquo;t an obvious way to volunteer time to help improve these systems. 💡&lt;/p&gt;
&lt;h2 id="free-stuff-getting-better-over-time"&gt;
Free stuff getting better over time
&lt;a class="heading-anchor" href="#free-stuff-getting-better-over-time" aria-label="Link to Free stuff getting better over time"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re reading this letter on a browser, you&amp;rsquo;ll notice I&amp;rsquo;ve spruced the website up a lot. I&amp;rsquo;m going to write more about the numerous subtle features a casual reader might miss.&lt;/p&gt;
&lt;p&gt;But every time I start to work on it, there&amp;rsquo;s this guilt of sinking time into &lt;a href="https://github.com/kaushikgopal/henry-hugo"&gt;the effort&lt;/a&gt;. But I&amp;rsquo;m writing this to remind future me: it&amp;rsquo;s ok. Working on &lt;a href="https://kau.sh/henry"&gt;Henry&lt;/a&gt; is meditative for me - low stakes programming that makes atleast one person happy (me).&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also something fulfilling about the idea of improving the work you give out for free, over time. How often can you say that about other free things in life? 🧘🏽&lt;/p&gt;
&lt;h1 id="resolutions--goals"&gt;
Resolutions &amp;amp; &lt;a href="https://kau.sh/letter/1#lets-kick-this-off"&gt;Goals&lt;/a&gt;
&lt;a class="heading-anchor" href="#resolutions--goals" aria-label="Link to Resolutions &amp;amp; Goals"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="tolerance-in-thinking-platformer-leaves-substack"&gt;
[Tolerance in thinking] Platformer leaves Substack
&lt;a class="heading-anchor" href="#tolerance-in-thinking-platformer-leaves-substack" aria-label="Link to [Tolerance in thinking] Platformer leaves Substack"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Casey Newton on &lt;a href="https://www.platformer.news/why-platformer-is-leaving-substack/"&gt;leaving substack&lt;/a&gt;. I thought this was a measured response and he went about it the right way. I was especially curious how he&amp;rsquo;d handle the usual questions around freedom of speech &amp;amp; tolerance in thinking. His FAQ at the end does a good job.&lt;/p&gt;
&lt;h2 id="self-care-back-to-weightlifting"&gt;
[Self care] Back to Weightlifting
&lt;a class="heading-anchor" href="#self-care-back-to-weightlifting" aria-label="Link to [Self care] Back to Weightlifting"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;My transformation from a 100kg (220 lbs) teenager to a 70kg (154 lbs) fit young adult was anything but easy. It wasn&amp;rsquo;t inspiration but severe back pain that drove me. An elderly chiropractor candidly remarked &amp;ldquo;you&amp;rsquo;re the youngest non-injured patient I&amp;rsquo;ve ever had in my career&amp;rdquo;. That scared the shit out of me cause that dude was &lt;strong&gt;old&lt;/strong&gt;. I learnt then that the only activity I was consistent with is weightlifting (thankfully).&lt;/p&gt;
&lt;figure &gt;
&lt;img src="workout-x.webp"
alt="workout image poster"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;m aiming to regain my former fitness by starting simple. For now, I&amp;rsquo;m alternating between two full-body workouts that I found on this slapstick &lt;a href="https://www.youtube.com/watch?v=U9ENCvFf9yQ&amp;amp;t=445s"&gt;YouTube&lt;/a&gt; channel.&lt;/p&gt;
&lt;figure &gt;
&lt;img src="workout-1.webp"
alt="workout image 1"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;figure &gt;
&lt;img src="workout-2.webp"
alt="workout image 2"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;p&gt;Next month, I&amp;rsquo;ll switch it up with a different set.&lt;/p&gt;
&lt;h1 id="signing-off"&gt;
Signing off
&lt;a class="heading-anchor" href="#signing-off" aria-label="Link to Signing off"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Thank you genuinely for subscribing or reading my letters. I&amp;rsquo;d love to always &lt;a href="https://kau.sh/contact/"&gt;hear more from you&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What would you like to see more or less of — tech insights, programming chatter, personal stories?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m finding my way. I&amp;rsquo;d appreciate all the help.&lt;/p&gt;
&lt;p&gt;Until the next one.&lt;/p&gt;</description><guid>https://kau.sh/letter/2/</guid><pubDate>Thu, 01 Feb 2024 20:00:00 GMT</pubDate></item><item><title>
Toggle window snapping with Keyboard Maestro</title><link>https://kau.sh/blog/toggle-move-resize-window-keyboard-maestro/</link><description>
&lt;p&gt;Shopify CEO Tobi Lütke in a tweet last year mentioned why he uses the &lt;a href="https://twitter.com/tobi/status/1479092213959254017?s=20"&gt;Rectangle app&lt;/a&gt; even through Raycast has some of these options already. Rectangle allows you to &amp;ldquo;toggle&amp;rdquo; the window to different positions.&lt;/p&gt;
&lt;p&gt;I was inspired by this and wanted to be able to do the same. But in keeping with my theme to &lt;a href="https://kau.sh/blog/simplify"&gt;Simplify&lt;/a&gt;, I didn&amp;rsquo;t want to add a new tool to my arsenal.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.stairways.com/action/kmdiscount?REF6JZA"&gt;Keyboard Maestro&lt;/a&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; to the rescue!&lt;/p&gt;
&lt;video controls
width="100%"
autoplay
muted
loop
playsinline&gt;
&lt;source src="https://github.com/kaushikgopal/km-macros/raw/master/screenshots/window-snap-toggling.mp4" type="video/mp4"&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/video&gt;
&lt;p&gt;This set of macros allow you to toggle between a few states:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Toggle to the left ½ ¼ ⅔ of the screen (with the same shortcut)&lt;/li&gt;
&lt;li&gt;Toggle to the right ½ ¼ ⅔ of the screen&lt;/li&gt;
&lt;li&gt;Toggle full screen and back&lt;/li&gt;
&lt;li&gt;Toggle to the center of the screen and back&lt;/li&gt;
&lt;li&gt;Toggle vertically&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="https://github.com/kaushikgopal/km-macros/blob/master/Window%20Movers%20Toggle%20Macros.kmmacros"&gt;Download the Keyboard Maestro Macro group here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;referral link&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/blog/toggle-move-resize-window-keyboard-maestro/</guid><pubDate>Sun, 16 Jul 2023 19:22:07 GMT</pubDate></item><item><title>
Share your macOS audio with multiple multiple bluetooth headphones or Airpods</title><link>https://kau.sh/blog/stream-audio-multiple-headphones-mac/</link><description>
&lt;p&gt;When I travel on airplanes, I prefer to download content onto my 14&amp;quot; Macbook&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; so I can watch it offline during the flight. When my wife travels with me, we like catching up on some of the shows that we like to watch together.&lt;/p&gt;
&lt;p&gt;But we both have our own pair of Airpods that we&amp;rsquo;d like to use to listen to the audio together. In the wired headphones days, I&amp;rsquo;d carry a headphone splitter that we&amp;rsquo;d plug both of our wired headphones into.&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/78/Headphone_mic_splitter_adapter.jpg/320px-Headphone_mic_splitter_adapter.jpg"
alt="Headphone splitter"
loading="lazy" decoding="async"
/&gt;
&lt;figcaption&gt;
&lt;a class="center" href="https://commons.wikimedia.org/wiki/File:Headphone_mic_splitter_adapter.jpg"&gt;
Courtesy: Wikimedia
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;This blog post provides instructions for the equivalent solution in our wireless/bluetooth headphones world.&lt;/p&gt;
&lt;h1 id="software"&gt;
Software
&lt;a class="heading-anchor" href="#software" aria-label="Link to Software"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;I&amp;rsquo;m going to use Rogue Amoeba&amp;rsquo;s excellent solution &lt;a href="https://rogueamoeba.com/loopback/"&gt;Loopback&lt;/a&gt; in the below instructions. I&amp;rsquo;m pretty sure you can also use &lt;a href="https://github.com/mattingalls/Soundflower"&gt;Soundflower&lt;/a&gt;, the native &amp;ldquo;Audio MIDI setup&amp;rdquo; app or other solutions. But Loopback makes this ludicrously easy.&lt;/p&gt;
&lt;h2 id="step-1-pair-headphones-to-the-mac"&gt;
Step 1: Pair headphones to the Mac
&lt;a class="heading-anchor" href="#step-1-pair-headphones-to-the-mac" aria-label="Link to Step 1: Pair headphones to the Mac"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pair each of the headphones individually to the Mac (as you typically would).&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="stream-audio.1.webp"
width="35%"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;After pairing the first set, you might have to disconnect them (temporarily) and proceed to pair the second set individually.&lt;/p&gt;
&lt;h2 id="step-2-create-a-virtual-multi-output-device"&gt;
Step 2: Create a Virtual multi-output device
&lt;a class="heading-anchor" href="#step-2-create-a-virtual-multi-output-device" aria-label="Link to Step 2: Create a Virtual multi-output device"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Create a new virtual device in Loopback &lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;video controls
width="100%"
autoplay
muted
loop
playsinline&gt;
&lt;source src="stream-audio.2.mp4" type="video/mp4"&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/video&gt;
&lt;h2 id="step-3-add-both-headphones-to-the-output-channel"&gt;
Step 3: Add both headphones to the output channel
&lt;a class="heading-anchor" href="#step-3-add-both-headphones-to-the-output-channel" aria-label="Link to Step 3: Add both headphones to the output channel"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Gen2-2023&lt;/code&gt; is the bluetooth headphones I use in the below instructions. Add both headphones to the Output channels.&lt;/p&gt;
&lt;video controls
width="100%"
autoplay
muted
loop
playsinline&gt;
&lt;source src="stream-audio.3a.mp4" type="video/mp4"&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/video&gt;
&lt;p&gt;If you&amp;rsquo;re wondering how both headphones connect directly, chalk it to the wonders of the Mac. While the first headphones is connected, connect your second pair (without disconnecting the first) and they both should be connected.&lt;/p&gt;
&lt;video controls
width="50%"
autoplay
muted
loop
playsinline&gt;
&lt;source src="stream-audio.3b.mp4" type="video/mp4"&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/video&gt;
&lt;p&gt;You probably will still only hear the output from one of the headphones, but we&amp;rsquo;re almost there.&lt;/p&gt;
&lt;h2 id="step-4-switch-mac-audio-to-new-virtual-device"&gt;
Step 4: Switch Mac audio to new virtual device
&lt;a class="heading-anchor" href="#step-4-switch-mac-audio-to-new-virtual-device" aria-label="Link to Step 4: Switch Mac audio to new virtual device"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;figure class="borderless"&gt;
&lt;div align="center"&gt;
&lt;img src="stream-audio.4.webp"
class="borderless"
width="60%"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re all aboard the Rogue Amoeba wagon, &lt;a href="https://rogueamoeba.com/soundsource/"&gt;Soundsource&lt;/a&gt; is another app they maintain, that makes it trivially easy to switch audio sources. For someone who keeps switching workstations, podcasts etc. this is delightful software.&lt;/em&gt;&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="stream-audio.5.gif"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;h2 id="step-5-play--enjoy"&gt;
Step 5: Play &amp;amp; Enjoy
&lt;a class="heading-anchor" href="#step-5-play--enjoy" aria-label="Link to Step 5: Play &amp;amp; Enjoy"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;video controls
width="100%"
autoplay
muted
loop
playsinline&gt;
&lt;source src="stream-audio.6.mp4" type="video/mp4"&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/video&gt;
&lt;p&gt;Loopback also allows you to control volumes separately which is a godsend when you have two picky people.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;An iPad would probably be better but I remain a iPhone + Macboook only kind of guy.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;This would be a &amp;ldquo;Multi-Output device&amp;rdquo; in the Audio MIDI app but Loopback simplifies these distinctions.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/blog/stream-audio-multiple-headphones-mac/</guid><pubDate>Sun, 29 Jan 2023 05:27:58 GMT</pubDate></item><item><title>
Keyboard Maestro as a Text Expander replacement</title><link>https://kau.sh/blog/keyboard-maestro-replace-text-expander/</link><description>
&lt;figure class="borderless"&gt;
&lt;div align="center"&gt;
&lt;img src="https://kau.sh/images/content/keyboard-maestro.webp"
class="borderless"
alt="keyboard maestro icon"
width="300"
loading="lazy" decoding="async"
/&gt;
&lt;figcaption&gt;
&lt;a class="center" href="https://yoolk.ninja/"&gt;
icon by Yoolk
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;If you&amp;rsquo;ve &lt;a href="https://daringfireball.net/linked/2022/07/25/textexpander-raises-41-million"&gt;recently&lt;/a&gt; needed a text expander utility, might I suggest the trusty &lt;a href="http://www.stairways.com/action/kmdiscount?REF6J"&gt;Keyboard Maestro&lt;/a&gt;.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;I switched from TextExpander → Alfred quite some time back. Somewhat recently, I again switched from Alfred → KM for a couple of reasons:&lt;/p&gt;
&lt;h2 id="1-one-tool-to-rule-them-all"&gt;
1. One tool to rule them all
&lt;a class="heading-anchor" href="#1-one-tool-to-rule-them-all" aria-label="Link to 1. One tool to rule them all"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Between work &amp;amp; home, I use multiple computers these days. Having to sync + maintain each of these different utilities across multiple computers is becoming tedious.&lt;/p&gt;
&lt;p&gt;Keyboard Maestro is a mainstay in my productivity toolbelt and isn&amp;rsquo;t going anywhere. Might as well double down on it for the things it does well.&lt;/p&gt;
&lt;h2 id="2-fixing-app-quirks"&gt;
2. Fixing app quirks
&lt;a class="heading-anchor" href="#2-fixing-app-quirks" aria-label="Link to 2. Fixing app quirks"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;One of the big problems I found with utilities like Alfred is that the text expansion would activate too quickly. Consequently, the expansion wouldn&amp;rsquo;t work in certain apps (like VSCode).&lt;/p&gt;
&lt;p&gt;With Keyboard Maestro though, you can add a micro delay,&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; ensuring the snippets work flawlessly everywhere.&lt;/p&gt;
&lt;figure &gt;
&lt;img src="km-textexpand-emoji.webp"
alt="keyboard maestro macro for an emoji text expansion"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;You can also limit the scope to just a few apps if you&amp;rsquo;re worried this delay will slow you down in non-problematic apps.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="3-mix-text-expansion-with-other-macros"&gt;
3. Mix text expansion with other macros
&lt;a class="heading-anchor" href="#3-mix-text-expansion-with-other-macros" aria-label="Link to 3. Mix text expansion with other macros"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Building on that, with Keyboard Maestro, you&amp;rsquo;re not limited to just text replacement.&lt;/p&gt;
&lt;p&gt;You can execute full-fledged macros with your text expansion. Here&amp;rsquo;s an example of how I add checklists in Google Docs.&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;figure &gt;
&lt;img src="https://kau.sh/images/content/km-gdoc-checklist.webp"
alt="keyboard maestro macro for inserting checklist in google docs"
loading="lazy" decoding="async"
/&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href="http://www.stairways.com/action/kmdiscount?REF6J"&gt;Keyboard Maestro&lt;/a&gt; remains one of the most powerful utilities for the Mac.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Referral link&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;I use 0.5s&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;It puzzles me that they haven&amp;rsquo;t assigned a default keyboard shortcut for this already.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/blog/keyboard-maestro-replace-text-expander/</guid><pubDate>Wed, 27 Jul 2022 07:00:00 GMT</pubDate></item><item><title>
Magic enter command for (fish/zsh) shell</title><link>https://kau.sh/blog/magic-enter-shell/</link><description>
&lt;p&gt;Two of the most common commands I run when I &lt;code&gt;cd&lt;/code&gt; into a directory are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git status&lt;/code&gt; (which i do through &lt;a href="https://kau.sh/blog/git-number"&gt;git-number&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ls -lh&lt;/code&gt; (aliased automatically as &lt;code&gt;ll&lt;/code&gt; through fish)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;If this directory is not a git repo, then I usually am thinking of command 2.&lt;/li&gt;
&lt;li&gt;If however it is a git repository then
&lt;ul&gt;
&lt;li&gt;I&amp;rsquo;d like to know if any files have been changed in this directory and&lt;/li&gt;
&lt;li&gt;which ones specifically (which is command 1).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wouldn&amp;rsquo;t it be nice if I could just hit the ↩ (enter key) and have this automatically happen?&lt;/p&gt;
&lt;video controls
width="100%"
autoplay
muted
loop
playsinline&gt;
&lt;source src="demo-magic-enter.mp4" type="video/mp4"&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/video&gt;
&lt;h2 id="solution-for-fish-users"&gt;
Solution for fish users
&lt;a class="heading-anchor" href="#solution-for-fish-users" aria-label="Link to Solution for fish users"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re using &lt;a href="https://fishshell.com/"&gt;fish&lt;/a&gt;, I got you covered:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# filename: fish/conf.d/magic-enter.fish&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; magic-enter-cmd --description &lt;span style="color:#e6db74"&gt;&amp;#34;Issue git status or ls on hitting enter in a dir&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set -l cmd ll
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set -l is_git_repository &lt;span style="color:#f92672"&gt;(&lt;/span&gt;fish -c &lt;span style="color:#e6db74"&gt;&amp;#34;git rev-parse --is-inside-work-tree &amp;gt;&amp;amp;2&amp;#34;&lt;/span&gt; 2&amp;gt;| grep true&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Special variable indicating git.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set -l in_root_folder &lt;span style="color:#f92672"&gt;(&lt;/span&gt;fish -c &lt;span style="color:#e6db74"&gt;&amp;#34;git rev-parse --show-toplevel &amp;gt;&amp;amp;2&amp;#34;&lt;/span&gt; 2&amp;gt;| grep &lt;span style="color:#f92672"&gt;(&lt;/span&gt;pwd&lt;span style="color:#f92672"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set -l repo_has_changes &lt;span style="color:#f92672"&gt;(&lt;/span&gt;git status -s --ignore-submodules&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dirty&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; test -n &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$is_git_repository&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; test -n &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$in_root_folder&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; test -n &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$repo_has_changes&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set cmd git-number
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; end
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; end
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; end
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo $cmd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; magic-enter
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set -l cmd &lt;span style="color:#f92672"&gt;(&lt;/span&gt;commandline&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; test -z &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$cmd&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; commandline -r &lt;span style="color:#f92672"&gt;(&lt;/span&gt;magic-enter-cmd&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; commandline -f suppress-autosuggestion
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; end
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; commandline -f execute
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bind &lt;span style="color:#ae81ff"&gt;\r&lt;/span&gt; magic-enter
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="solution-for-zsh-users"&gt;
Solution for zsh users
&lt;a class="heading-anchor" href="#solution-for-zsh-users" aria-label="Link to Solution for zsh users"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re using &lt;a href="https://zsh.sourceforge.io"&gt;zsh&lt;/a&gt;, I adapted the &lt;a href="https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/magic-enter"&gt;native solution&lt;/a&gt; like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# filename: magic-enter.plugin.zsh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Default commands&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;MAGIC_ENTER_GIT_COMMAND:=&lt;span style="color:#e6db74"&gt;&amp;#34;git-number&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt; &lt;span style="color:#75715e"&gt;# run when in a git repository&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;MAGIC_ENTER_OTHER_COMMAND:=&lt;span style="color:#e6db74"&gt;&amp;#34;ll&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt; &lt;span style="color:#75715e"&gt;# run anywhere else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;magic-enter&lt;span style="color:#f92672"&gt;()&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Only run MAGIC_ENTER commands when in PS1 and command line is empty&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#User_002dDefined-Widgets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;[[&lt;/span&gt; -n &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$BUFFER&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$CONTEXT&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; !&lt;span style="color:#f92672"&gt;=&lt;/span&gt; start &lt;span style="color:#f92672"&gt;]]&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; is_git_repository&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;git rev-parse --is-inside-work-tree&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; in_repo_root_folder&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;git rev-parse --show-toplevel&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; repo_has_changes&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;git status -s --ignore-submodules&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dirty&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$is_git_repository&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; true &lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$in_repo_root_folder&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $PWD &lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt; ! -z &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$repo_has_changes&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BUFFER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$MAGIC_ENTER_GIT_COMMAND&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BUFFER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$MAGIC_ENTER_OTHER_COMMAND&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Wrapper for the accept-line zle widget (run when pressing Enter)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# If the wrapper already exists don&amp;#39;t redefine it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;((&lt;/span&gt; ! &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;+functions[_magic-enter_accept-line]&lt;span style="color:#e6db74"&gt;}&lt;/span&gt; &lt;span style="color:#f92672"&gt;))&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$widgets&lt;span style="color:#e6db74"&gt;[accept-line]&amp;#34;&lt;/span&gt; in
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Override the current accept-line widget, calling the old one&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user:*&lt;span style="color:#f92672"&gt;)&lt;/span&gt; zle -N _magic-enter_orig_accept-line &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;widgets[accept-line]#user:&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; _magic-enter_accept-line&lt;span style="color:#f92672"&gt;()&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; magic-enter
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zle _magic-enter_orig_accept-line -- &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$@&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt; ;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# If no user widget defined, call the original accept-line widget&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; builtin&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; _magic-enter_accept-line&lt;span style="color:#f92672"&gt;()&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; magic-enter
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zle .accept-line
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt; ;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;esac&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;zle -N accept-line _magic-enter_accept-line
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Remember to source this in your &lt;code&gt;.zshrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source magic-enter.plugin.zsh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="revisions"&gt;
Revisions
&lt;a class="heading-anchor" href="#revisions" aria-label="Link to Revisions"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Make a change to only check git status in a root folder.&lt;/li&gt;
&lt;li&gt;Reddit &lt;code&gt;/u/colemaker360&lt;/code&gt; &lt;a href="https://www.reddit.com/r/commandline/comments/w75msb/comment/ihiub1s/"&gt;reminded me&lt;/a&gt; that the &lt;code&gt;^/dev/null&lt;/code&gt; redirect strategy is now &lt;a href="https://github.com/fish-shell/fish-shell/issues/4394#issuecomment-366098782"&gt;deprecated&lt;/a&gt; with fish 3.&lt;/li&gt;
&lt;li&gt;Redditor &lt;code&gt;/u/jblondreddit&lt;/code&gt; &lt;a href="https://www.reddit.com/r/fishshell/comments/w75nwt/comment/ihjpicp/"&gt;pointed out&lt;/a&gt; that porcelain can be a slow.&lt;/li&gt;
&lt;li&gt;Add solution for zsh users&lt;/li&gt;
&lt;/ul&gt;</description><guid>https://kau.sh/blog/magic-enter-shell/</guid><pubDate>Sat, 23 Jul 2022 19:50:31 GMT</pubDate></item><item><title>
Manipulating images &amp; PDFs using CLI commands</title><link>https://kau.sh/blog/terminal-cli-image-pdf-conversion/</link><description>
&lt;p&gt;Whenever I need to convert, merge, or combine images or PDF files, I pull out my Terminal and attempt doing it first with CLI (command line interface) commands. Over time I&amp;rsquo;ve built an arsenal of CLI commands that 9/10 times does the trick faster than any other program.&lt;/p&gt;
&lt;h4 id="prerequisites"&gt;
Prerequisites
&lt;a class="heading-anchor" href="#prerequisites" aria-label="Link to Prerequisites"&gt;####&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;Most of the image manipulation commands require &lt;a href="https://imagemagick.org/index.php"&gt;imagemagick&lt;/a&gt; and the PDF ones require &lt;a href="https://poppler.freedesktop.org/"&gt;poppler&lt;/a&gt;. Both of which are just a homebrew install away for macOS:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# image utilities&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install &lt;span style="color:#e6db74"&gt;&amp;#34;imagemagick&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# pdf utilities&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install &lt;span style="color:#e6db74"&gt;&amp;#34;poppler&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="merging"&gt;
Merging
&lt;a class="heading-anchor" href="#merging" aria-label="Link to Merging"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="merge-images-horizontallyvertically"&gt;
Merge images horizontally/vertically
&lt;a class="heading-anchor" href="#merge-images-horizontallyvertically" aria-label="Link to Merge images horizontally/vertically"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## horizontal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert +append image_1.png image_2.png merged
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## vertical&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -append image_1.png image_2.png merged // vertical
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# using montage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# slightly better as it maintains transparency within images&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## horizontal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;montage 0_index.png 1_post.png -background none -tile 2x1 -geometry +0+0 PNG32:out.png
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## vertical&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;montage 0_index.png 1_post.png -background none -tile 1x2 -geometry +0+0 PNG32:out.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="merge-images-and-pdfs"&gt;
Merge images and PDFs
&lt;a class="heading-anchor" href="#merge-images-and-pdfs" aria-label="Link to Merge images and PDFs"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert 1.png 2.pdf merged.pdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="merge-pdfs"&gt;
Merge PDFs
&lt;a class="heading-anchor" href="#merge-pdfs" aria-label="Link to Merge PDFs"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# pdfunite ships with poppler&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pdfunite output-1.pdf output-2.pdf output-3.pdf merged-1-3.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pdfunite output-4.pdf output-5.pdf merged-4-5.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# using native tools that comes with the macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/System/Library/Automator/Combine PDF Pages.action/Contents/Resources/join.py&amp;#34;&lt;/span&gt; -o merged.pdf source1.pdf source2.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# using ghostscript [also works with encrypted PDFs]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gs -q -dNOPAUSE -dBATCH -sDEVICE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;pdfwrite -sOutputFile&lt;span style="color:#f92672"&gt;=&lt;/span&gt;merged.pdf source1.pdf source2.pdf source3.pdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="splitting"&gt;
Splitting
&lt;a class="heading-anchor" href="#splitting" aria-label="Link to Splitting"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="split-multi-page-pdf-into-single-page-pdfs"&gt;
Split multi-page PDF into single page PDFs
&lt;a class="heading-anchor" href="#split-multi-page-pdf-into-single-page-pdfs" aria-label="Link to Split multi-page PDF into single page PDFs"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# pdfseparate &amp;amp; pdfunite ship with poppler&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# split input.pdf into output-1.pdf output-2.pdf ... etc.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pdfseparate input.pdf output-%d.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# split input.pdf from page 2 till the end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pdfseparate -f &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; input.pdf output-%d.pdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="replacing-single-pages-in-pdf"&gt;
Replacing single pages in PDF
&lt;a class="heading-anchor" href="#replacing-single-pages-in-pdf" aria-label="Link to Replacing single pages in PDF"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A common usecase is to swap out a single page in a pdf. &lt;code&gt;poppler&lt;/code&gt; doesn&amp;rsquo;t have a
readymade command for this, instead i just use &lt;code&gt;pdfseparate&lt;/code&gt; + &lt;code&gt;pdfunite&lt;/code&gt; for
this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fish" data-lang="fish"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# input has 10 pages; special has 3 pages
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# replace pages 5,6,7 in input with special pages
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;pdfseparate&lt;/span&gt; input.pdf input-%d.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;pdfseparate&lt;/span&gt; special.pdf special-%d.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# using fish shell
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;seq&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;pdfunite&lt;/span&gt; input-$i
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="resizingcompression"&gt;
Resizing/Compression
&lt;a class="heading-anchor" href="#resizingcompression" aria-label="Link to Resizing/Compression"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="by--or-boundary"&gt;
By % or boundary
&lt;a class="heading-anchor" href="#by--or-boundary" aria-label="Link to By % or boundary"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -resize 60% src_img.png src_img_reduced.png
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -resize 128x128 src_img.gif src_img_reduced.gif
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Doesn&amp;rsquo;t overwrite&lt;/li&gt;
&lt;li&gt;60% is good for documents&lt;/li&gt;
&lt;li&gt;75% is acceptable image quality (though you probably want higher)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="by-keeping-aspect-ratio--max-dimension"&gt;
By keeping aspect ratio &amp;amp; max dimension
&lt;a class="heading-anchor" href="#by-keeping-aspect-ratio--max-dimension" aria-label="Link to By keeping aspect ratio &amp;amp; max dimension"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sips -Z &lt;span style="color:#ae81ff"&gt;800&lt;/span&gt; input.png --out output.png
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Z maintain aspect ratio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 800 max height and width to be used&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="in-directory"&gt;
In directory
&lt;a class="heading-anchor" href="#in-directory" aria-label="Link to In directory"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# resize all images in directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; f in *.jpeg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; convert -resize 60% &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$f&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; dest/src_img_reduced.png
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="converting"&gt;
Converting
&lt;a class="heading-anchor" href="#converting" aria-label="Link to Converting"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="dng--jpg"&gt;
DNG → JPG
&lt;a class="heading-anchor" href="#dng--jpg" aria-label="Link to DNG → JPG"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# sips ships natively with macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sips -Z &lt;span style="color:#ae81ff"&gt;3072&lt;/span&gt; -s format jpeg input.dng --out output.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Z maintain aspect ratio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# -s format jpeg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Overwrites&lt;/li&gt;
&lt;li&gt;Aggressively reduces&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="png--jpg"&gt;
PNG → JPG
&lt;a class="heading-anchor" href="#png--jpg" aria-label="Link to PNG → JPG"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# sips ships natively with macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sips -s format png input.jpg --out output.jpeg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="heic--jpg"&gt;
HEIC → JPG
&lt;a class="heading-anchor" href="#heic--jpg" aria-label="Link to HEIC → JPG"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# sips ships natively with macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sips -s format jpeg input.heic --out output.jpeg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pdf--jpg"&gt;
PDF → JPG
&lt;a class="heading-anchor" href="#pdf--jpg" aria-label="Link to PDF → JPG"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -density &lt;span style="color:#ae81ff"&gt;150&lt;/span&gt; -quality &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt; -flatten -sharpen 0x1.0 -trim input.pdf output.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3rd page of pdf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert input.pdf&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt; output.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert all pages (2 means 2 digits will show on page count)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert input.pdf output-%02d.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# pdftoppm ships with poppler&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# output is a prefix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 150 is DPI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pdftoppm -jpeg -r &lt;span style="color:#ae81ff"&gt;150&lt;/span&gt; input.pdf output
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="jpg--pdf"&gt;
JPG → PDF
&lt;a class="heading-anchor" href="#jpg--pdf" aria-label="Link to JPG → PDF"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert 1.jpg 2.jpg merged.pdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="jpg--a4-paper-size-pdf"&gt;
JPG → (A4 paper size) PDF
&lt;a class="heading-anchor" href="#jpg--a4-paper-size-pdf" aria-label="Link to JPG → (A4 paper size) PDF"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -density &lt;span style="color:#ae81ff"&gt;80&lt;/span&gt; input.jpeg -background white &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;&lt;/span&gt; -page a4 &lt;span style="color:#75715e"&gt;# -page Letter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; output.pdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="jpg--png"&gt;
JPG → PNG
&lt;a class="heading-anchor" href="#jpg--png" aria-label="Link to JPG → PNG"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# sips ships natively with macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sips -s format png input.jpg --out output.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="png--webp"&gt;
PNG → WEBP
&lt;a class="heading-anchor" href="#png--webp" aria-label="Link to PNG → WEBP"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# install webp utility&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install webp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cwebp input.png -o output.webp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cwebp -q &lt;span style="color:#ae81ff"&gt;75&lt;/span&gt; input.png -o output.webp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# -q 75 refers to the compression rate.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="svg--webp"&gt;
SVG → WEBP
&lt;a class="heading-anchor" href="#svg--webp" aria-label="Link to SVG → WEBP"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -background none -density &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt; input.svg output.webp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="svg--png"&gt;
SVG → PNG
&lt;a class="heading-anchor" href="#svg--png" aria-label="Link to SVG → PNG"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -background none -density &lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt; -resize 48x is_logo_location.svg is_logo_location.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="png--gif"&gt;
PNG → GIF
&lt;a class="heading-anchor" href="#png--gif" aria-label="Link to PNG → GIF"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -delay &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt; -loop &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; *.png output.gif
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="movmp4--gif"&gt;
MOV/MP4 → GIF
&lt;a class="heading-anchor" href="#movmp4--gif" aria-label="Link to MOV/MP4 → GIF"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# convert ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir frames
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# mov or m4v&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ffmpeg -i input.mov -vf scale=320:-1,format=rgb8,format=rgb24 -r 10 frames/ffout%3d.png&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ffmpeg -i input.mov -vf scale&lt;span style="color:#f92672"&gt;=&lt;/span&gt;320:-1 -r &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt; frames/ffout%3d.png
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convert -delay &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt; -loop &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; frames/ffout*.png frames/output.gif
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# scale [width in px]:-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# r framerate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="manipulating"&gt;
Manipulating
&lt;a class="heading-anchor" href="#manipulating" aria-label="Link to Manipulating"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="remove-transparency"&gt;
Remove transparency
&lt;a class="heading-anchor" href="#remove-transparency" aria-label="Link to Remove transparency"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# flattens png to a solid color&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# mogrify ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mogrify -background white -flatten input*.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="get-information-from-image"&gt;
Get information from image
&lt;a class="heading-anchor" href="#get-information-from-image" aria-label="Link to Get information from image"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="is-image-transparent"&gt;
Is image transparent?
&lt;a class="heading-anchor" href="#is-image-transparent" aria-label="Link to Is image transparent?"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# identify ships with imagemagick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;identify -format &lt;span style="color:#e6db74"&gt;&amp;#39;%[channels]&amp;#39;&lt;/span&gt; foo.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="list-image-dimensions"&gt;
List image dimensions
&lt;a class="heading-anchor" href="#list-image-dimensions" aria-label="Link to List image dimensions"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;identify -format &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#34;%w %h&amp;#39;&lt;/span&gt; foo.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;I&amp;rsquo;ll keep adding more as I discover new use cases.&lt;/em&gt;&lt;/p&gt;
&lt;!-- adding pdf watermark to pdfs
https://talk.automators.fm/t/adding-file-names-to-pdfs-in-macos/12770/5 --&gt;</description><guid>https://kau.sh/blog/terminal-cli-image-pdf-conversion/</guid><pubDate>Fri, 22 Jul 2022 03:40:45 GMT</pubDate></item><item><title>
Remove Terminal.app from Alfred &amp; Spotlight</title><link>https://kau.sh/blog/remove-terminal-alfred-spotlight/</link><description>
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="./remove-terminal-alfred.png"
alt="Spotlight Alfred show Terminal.app and iTerm"
loading="lazy" decoding="async"
/&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;I use &lt;a href="https://iterm2.com/"&gt;iTerm&lt;/a&gt; as my terminal of choice.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; It constantly annoys me when I use &lt;a href="https://www.alfredapp.com/"&gt;Alfred&lt;/a&gt; or Spotlight that the Terminal.app (native macOS) app also shows up in the search results.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is especially annoying on new computers when Alfred hasn&amp;rsquo;t learnt my preferences as Terminal.app would show up first in the results.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="options"&gt;
Options
&lt;a class="heading-anchor" href="#options" aria-label="Link to Options"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Quick googling shows two options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add a Spotlight comment &lt;code&gt;alfred:ignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the app to your Spotlight &amp;ldquo;privacy&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Option 1 is made a little complicated owing to the fact that you can&amp;rsquo;t add spotlight comments to native &amp;ldquo;Utilities&amp;rdquo; app on the Mac. I managed to do this but this option doesn’t work.&lt;/p&gt;
&lt;p&gt;At first, Option 2 might also seem tricky since the file picker doesn&amp;rsquo;t allow you to pick Utilities apps again. But there&amp;rsquo;s an easy workaround:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open Spotlight Preferences &amp;gt; Privacy Tab&lt;/li&gt;
&lt;li&gt;Open new Finder window &amp;amp; search for &amp;ldquo;Terminal.app&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Drag Terminal.app search result to Privacy Tab on Spotlight preferences&lt;/li&gt;
&lt;li&gt;type &amp;ldquo;Reload&amp;rdquo; in Alfred&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, whenever I search for &amp;ldquo;Term&amp;rdquo;, I only see &amp;ldquo;iTerm&amp;rdquo; show up in my search results.&lt;/p&gt;
&lt;h2 id="video"&gt;
Video
&lt;a class="heading-anchor" href="#video" aria-label="Link to Video"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;video controls
width="100%"
autoplay
muted
loop
playsinline&gt;
&lt;source src="./remove-terminal-alfred-spotlight.mp4" type="video/mp4"&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/video&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Why I use iTerm is for another blog post.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/blog/remove-terminal-alfred-spotlight/</guid><pubDate>Sun, 29 May 2022 07:00:00 GMT</pubDate></item><item><title>
Hacking your keyboard with karabiner</title><link>https://kau.sh/blog/hacking-your-keyboard/</link><description>
&lt;div data-callout-metadata="" data-callout-fold="" data-callout="fyi" class="callout"&gt;
&lt;div class="callout-title" dir="auto"&gt;
&lt;div class="callout-icon"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-info"&gt;&lt;circle cx="12" cy="12" r="10"&gt;&lt;/circle&gt;&lt;path d="M12 16v-4"&gt;&lt;/path&gt;&lt;path d="M12 8h.01"&gt;&lt;/path&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;div class="callout-title-inner"&gt;
Update
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="callout-content"&gt;
&lt;p&gt;I&amp;rsquo;ve since come up with an easier way to maintain my rules. This post talks of some of the cool things you can do with Karabiner. But if you want a more maintainable way of customizing all this, read &lt;a href="https://kau.sh/blog/karabiner-kt"&gt;my other post&lt;/a&gt; instead.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;tl;dr:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install yqrashawn/goku/goku
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir -p ~/.config &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cd ~/.config
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;touch karabiner/karabiner.json
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;touch karabiner.edn
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# update your edn file with a sample from here https://github.com/yqrashawn/GokuRakuJoudo/blob/master/tutorial.md&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# or mine: https://gist.github.com/kaushikgopal/ff7a92bbc887e59699c804b59074a126&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;goku
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="background"&gt;
Background
&lt;a class="heading-anchor" href="#background" aria-label="Link to Background"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;I&amp;rsquo;ve been messing with mechanical keyboards recently.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; There was one in particular which is a 60% layout that I fell in love with.&lt;/p&gt;
&lt;p&gt;The trouble with 60% keyboards though is that they can be pretty constraining for some basic operations (like navigation). Notice there aren&amp;rsquo;t dedicated keys for the up/left/down/arrows.&lt;/p&gt;
&lt;figure &gt;
&lt;div align="center"&gt;
&lt;img src="https://kau.sh/images/content/keyboard-layouts.webp"
alt="ANSI Keyboard Layout"
loading="lazy" decoding="async"
/&gt;
&lt;figcaption&gt;
&lt;a class="center" href="https://commons.wikimedia.org/wiki/File:ANSI_Keyboard_Layout_Diagram_with_Form_Factor.svg"&gt;
Courtesy: Wikipedia
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Given these constraints, you have to get a little creative with how you use a keyboard. I added a bunch of mods for the keyboard using the mechanical keyboard&amp;rsquo;s included software configurator. I liked these mods so much that I wanted to find a way to use these mods with &lt;em&gt;any&lt;/em&gt; keyboard I use.&lt;/p&gt;
&lt;p&gt;The easiest way I&amp;rsquo;ve found on the Mac to do this is using &lt;a href="https://karabiner-elements.pqrs.org/"&gt;Karabiner&lt;/a&gt;. Karabiner intercepts every keystroke and allows you to send alternative signals.&lt;/p&gt;
&lt;p&gt;For example, a common mod that a lot of programmers like to do is remap their Caps Lock key -&amp;gt; Escape. So if I tap the Caps Lock key, it instead emulates hitting the Escape key. You can do this pretty easily with Karabiner but it barely scratches the surface of Karabiner&amp;rsquo;s true power.&lt;/p&gt;
&lt;h2 id="complex-modifications"&gt;
Complex modifications:
&lt;a class="heading-anchor" href="#complex-modifications" aria-label="Link to Complex modifications:"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Where Karabiner will truly shine is when you want to do slightly more complex things: for example, take the case of navigation with 60% keyboards. While they don&amp;rsquo;t come with dedicated arrow keys you can emulate navigation in a pretty slick way (especiallly for us vim users).&lt;/p&gt;
&lt;p&gt;Instead of moving my fingers all the way to the bottom right of my keyboard and aiming for the arrow keys what if I could just keep my fingers on my home row and navigate like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tap caps lock once -&amp;gt; Escape key
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold caps lock -&amp;gt; left_control
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold caps lock and press h -&amp;gt; left arrow
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold caps lock and press j -&amp;gt; down arrow
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold caps lock and press k -&amp;gt; up arrow
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold caps lock and press l -&amp;gt; right arrow
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can of course choose to map any key combo (for example right shift key + W/A/S/D). I chose H/J/K/L cause I&amp;rsquo;m a vim user and I love just using h/j/k/l to navigate anywhere on my Mac!&lt;/p&gt;
&lt;h2 id="more-complex-modifications"&gt;
More Complex modifications:
&lt;a class="heading-anchor" href="#more-complex-modifications" aria-label="Link to More Complex modifications:"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Even that, just scratches the surface of what you can do with Karabiner. Another quick hack I use and love (as a programmer):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tap [ once -&amp;gt; type &amp;#34;[&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold [ and tap ] key once -&amp;gt; type &amp;#34;{&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tap ] once -&amp;gt; type &amp;#34;]&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold ] and tap [ key once -&amp;gt; type &amp;#34;}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you&amp;rsquo;re a programmer this makes it easier to type curly braces without contorting your fingers and flaring up that RSI. For typing paranthesis there&amp;rsquo;s an even better one:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;left_shift once -&amp;gt; type &amp;#34;(&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold left_shift -&amp;gt; use as a regular shift key modifier
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;right_shift once -&amp;gt; type &amp;#34;)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold right_shift -&amp;gt; used as a regular shift key modifier
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="but-theres-more"&gt;
But there&amp;rsquo;s more!
&lt;a class="heading-anchor" href="#but-theres-more" aria-label="Link to But there’s more!"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Apart from just modifying your key strokes, you can do advanced stuff like launching programs too. For example I typically switch between 3 applications pretty often: &lt;a href="https://iterm2.com/"&gt;iTerm&lt;/a&gt;, &lt;a href="https://www.mozilla.org/en-US/firefox/"&gt;Firefox&lt;/a&gt;, &lt;a href="https://culturedcode.com/things/"&gt;Things&lt;/a&gt;. With Karabiner, I use the same technique but switch programs pretty quickly:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold o (for &amp;#34;open&amp;#34;) + tap i -&amp;gt; launch &amp;#34;iTerm&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold o + tap f -&amp;gt; launch &amp;#34;Firefox&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold o + tap t -&amp;gt; launch &amp;#34;Things&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tap o once -&amp;gt; type &amp;#34;o&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This makes switching between apps almost instant. I don&amp;rsquo;t have to carefully Cmd + Tab, visually recognize each icon (adding one extra cognitive step 😁) and then launch it. This might seem frivolous at first but once you start using this quick open mode like functionality, it&amp;rsquo;s hard to go back to Cmd Tabbing.&lt;/p&gt;
&lt;h3 id="turbocharge-mode-karabiner--keyboard-maestro"&gt;
Turbocharge mode (Karabiner + Keyboard Maestro)
&lt;a class="heading-anchor" href="#turbocharge-mode-karabiner--keyboard-maestro" aria-label="Link to Turbocharge mode (Karabiner &amp;#43; Keyboard Maestro)"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;I swear by &lt;a href="http://www.stairways.com/action/kmdiscount?REF6JZA"&gt;Keyboard Maestro&lt;/a&gt; and use a lot of my macros pretty often. With Karabiner, I can map certain keyboard strokes to instead launch macros. For example, if I want to quickly Google something, I hold &amp;ldquo;o&amp;rdquo; then tap &amp;ldquo;g&amp;rdquo; -&amp;gt; this shows an input dialog to take in my text, then launches a new tab in firefox with a url to google prepoulated with my query.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hold &amp;#34;s&amp;#34; + tap g -&amp;gt; google for something on the web
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This kind of usage in conjunction with Keyboard Maestro basically unleashes the power of your Mac.&lt;/p&gt;
&lt;h1 id="how-do-i-do-this"&gt;
How do I do this?
&lt;a class="heading-anchor" href="#how-do-i-do-this" aria-label="Link to How do I do this?"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Before you head to the races and start using Karabiner though there&amp;rsquo;s one caveat:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Use &lt;a href="https://github.com/yqrashawn/GokuRakuJoudo#intro"&gt;Goku&lt;/a&gt; to organize your Karabiner&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;See the problem with Karabiner is that if you want to start doing the tricks I mention above, you pretty much have to start meddling directly with this file called &lt;code&gt;karabiner.json&lt;/code&gt;. Let&amp;rsquo;s just say json is not the most maintainable format for this kind of stuff.&lt;/p&gt;
&lt;p&gt;After meddling with Karabiner for a few days, it was clearly getting unwieldy to maintain the json file. So on an exaseperated whim, I went searching for a way to make it easier to deal with Karabiner and found the wonderful &lt;a href="https://github.com/yqrashawn/GokuRakuJoudo"&gt;Goku&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="enter-goku"&gt;
Enter &lt;a href="https://github.com/yqrashawn/GokuRakuJoudo#intro"&gt;Goku&lt;/a&gt;
&lt;a class="heading-anchor" href="#enter-goku" aria-label="Link to Enter Goku"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Goku basically is a DSL where you can write a nice and condensed form of the same code you would otherwise wrangle up in your karabiner.json. You write the code in this special format called &lt;a href="https://github.com/edn-format/edn"&gt;&amp;ldquo;extensible data notation&amp;rdquo; (edn)&lt;/a&gt;. Goku then reads that edn format and generates the karabiner.json file for you.&lt;/p&gt;
&lt;p&gt;For context:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;my &lt;a href="https://gist.github.com/kaushikgopal/c802ca81044066f7d93a50c5269cc812"&gt;&lt;code&gt;karabiner.json&lt;/code&gt;&lt;/a&gt; file currently has about 920 lines&lt;/li&gt;
&lt;li&gt;my &lt;a href="https://gist.github.com/kaushikgopal/ff7a92bbc887e59699c804b59074a126"&gt;&lt;code&gt;karabiner.edn&lt;/code&gt;&lt;/a&gt; file on the other hand has 140 lines (and most of it is liberal commenting and whitespace to combat &lt;code&gt;edn&lt;/code&gt;&amp;rsquo;s terseness)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-edn" data-lang="edn"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#e6db74"&gt;:des&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;o-mode: quick open&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;:rules&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;:o-mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#e6db74"&gt;:f&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;:open&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/Applications/Firefox.app&amp;#34;&lt;/span&gt;] ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#e6db74"&gt;:g&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;:km&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;0) Search Google&amp;#34;&lt;/span&gt;] ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#e6db74"&gt;:i&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;:open&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/Applications/iTerm.app&amp;#34;&lt;/span&gt;] ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#e6db74"&gt;:q&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;:km&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;open: Quip&amp;#34;&lt;/span&gt;] ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#e6db74"&gt;:t&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;:open&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/Applications/Things3.app&amp;#34;&lt;/span&gt;] ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#e6db74"&gt;:des&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;right cmd -&amp;gt; right ctrl&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;:rules&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;&lt;span style="color:#f92672"&gt;##&lt;/span&gt;right_command &lt;span style="color:#e6db74"&gt;:right_control&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;:apl-usb-int&lt;/span&gt; &lt;span style="color:#e6db74"&gt;:apl-bt&lt;/span&gt; &lt;span style="color:#e6db74"&gt;:ap2&lt;/span&gt;] ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#e6db74"&gt;:des&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;left shift once -&amp;gt; (&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;:rules&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;&lt;span style="color:#f92672"&gt;##&lt;/span&gt;left_shift &lt;span style="color:#e6db74"&gt;:left_shift&lt;/span&gt; nil {&lt;span style="color:#e6db74"&gt;:alone&lt;/span&gt; &lt;span style="color:#e6db74"&gt;:!S9&lt;/span&gt;} ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#e6db74"&gt;:des&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;right shift once -&amp;gt; )&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;:rules&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;&lt;span style="color:#f92672"&gt;##&lt;/span&gt;right_shift &lt;span style="color:#e6db74"&gt;:right_shift&lt;/span&gt; nil {&lt;span style="color:#e6db74"&gt;:alone&lt;/span&gt; &lt;span style="color:#e6db74"&gt;:!S0&lt;/span&gt;} ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Speaking as a programmer the edn format is quite possibly the most terse, terrible format I&amp;rsquo;ve encountered. I gave a quick look at &lt;a href="https://github.com/yqrashawn/GokuRakuJoudo/blob/master/examples.org"&gt;some of the examples&lt;/a&gt; and almost abandoned my Goku effort half way.&lt;/p&gt;
&lt;p&gt;But after spending an 11 hour flight back home fiddling and learning how to use Goku, I&amp;rsquo;ve gotten a decent hang of the format and I admit it&amp;rsquo;s &lt;em&gt;super&lt;/em&gt; mantainable.&lt;/p&gt;
&lt;h2 id="how-to-read-and-use-goku"&gt;
How to read and use Goku
&lt;a class="heading-anchor" href="#how-to-read-and-use-goku" aria-label="Link to How to read and use Goku"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m not going to explain how to use Goku, but I&amp;rsquo;ll tell you what helped me pick it up:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Read this &lt;a href="https://medium.com/@nikitavoloboev/karabiner-god-mode-7407a5ddc8f6"&gt;fantastic blog post by Nikita Voloboev&lt;/a&gt; once&lt;/li&gt;
&lt;li&gt;Follow along then with the &lt;a href="https://github.com/yqrashawn/GokuRakuJoudo/blob/master/tutorial.md"&gt;official tutorial&lt;/a&gt; as they explain the basics&lt;/li&gt;
&lt;li&gt;Read the blog post from step 1 again, given you&amp;rsquo;re a little more familiar with the format&lt;/li&gt;
&lt;li&gt;Read my &lt;a href="https://gist.github.com/kaushikgopal/ff7a92bbc887e59699c804b59074a126"&gt;&lt;code&gt;karabiner.edn&lt;/code&gt;&lt;/a&gt; file&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I spent a lot of time commenting &lt;a href="https://gist.github.com/kaushikgopal/ff7a92bbc887e59699c804b59074a126"&gt;my edn file&lt;/a&gt; with the hope of making it more readable, so hope that helps. I plan on making a youtube video at some point demoing all this but until that happens, hope this blog post is helpful.&lt;/p&gt;
&lt;p&gt;Hit me up on &lt;a href="https://twitter.com/kaushikgopal"&gt;Twitter&lt;/a&gt; for queries or comments. Super curious to see other creative hacks people can come up with this technique.&lt;/p&gt;
&lt;h3 id="example-edns"&gt;
Example edns
&lt;a class="heading-anchor" href="#example-edns" aria-label="Link to Example edns"&gt;###&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/yqrashawn/GokuRakuJoudo/blob/master/in-the-wild.md"&gt;goku repo example&amp;rsquo;s in the
wild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kchen0x/k-goku/blob/master/karabiner.edn"&gt;k-goku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/nikitavoloboev/dotfiles/blob/178ed88fadaeb889e8a5431e9790f0791dd75b05/karabiner/karabiner.edn#L718"&gt;nikitavoloboev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yqrashawn/GokuRakuJoudo/blob/master/examples.org"&gt;examples.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Mechanical keyboards are a costly unhealthy obsession. I switch between an &lt;a href="http://en.obins.net/anne-pro2"&gt;Anne Pro 2&lt;/a&gt; and a &lt;a href="https://mechanicalkeyboards.com/shop/index.php?l=product_list&amp;amp;c=647"&gt;TADA68&lt;/a&gt; these days.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><guid>https://kau.sh/blog/hacking-your-keyboard/</guid><pubDate>Wed, 25 Dec 2019 07:00:00 GMT</pubDate></item><item><title>
Speed up your Android Studio</title><link>https://kau.sh/blog/android-studio-slow-as-fxxx/</link><description>
&lt;p&gt;I use a 13&amp;quot; MacBook Pro at work these days. Android Studio frequently sent my machine into a tailspin.&lt;/p&gt;
&lt;p&gt;Over time, I&amp;rsquo;ve had to tweak and update my AS settings to make AS work well on the 13&amp;quot;. I figured I should post them here for posterity and the benefit of other AndroidDevs battling with deathly slow AS experiences.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m posting the abridged instructions and linking to the blog posts that led me to these settings, if you care for the details.&lt;/p&gt;
&lt;h1 id="switch-to-a-local-gradle-distribution"&gt;
Switch to a local gradle distribution
&lt;a class="heading-anchor" href="#switch-to-a-local-gradle-distribution" aria-label="Link to Switch to a local gradle distribution"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -s &lt;span style="color:#e6db74"&gt;&amp;#34;https://get.sdkman.io&amp;#34;&lt;/span&gt; | bash &lt;span style="color:#75715e"&gt;# install sdkman&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# install your preferred version of gradle&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sdk install gradle 5.4.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sdk default gradle 5.4.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gradle --status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once you have a local distribution of gradle installed, switch the &amp;ldquo;Gradle home:&amp;rdquo; setting in your Android Studio project to point to your local gradle distribution. You&amp;rsquo;ll have to do these for all your projects individually.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://kau.sh/images/content/as-local-gradle.png" alt="Android Studio &amp;gt; Preferences &amp;gt; Build, Execution, Deployment &amp;gt; Gradle"&gt;&lt;/p&gt;
&lt;p&gt;With this setup, when you run gradle on the command line or Android Studio, they&amp;rsquo;ll share the same gradle daemon instances.&lt;/p&gt;
&lt;h2 id="--also-make-sure-the-daemons-from-as-and-your-command-line-are-compatible"&gt;
☝️ also make sure the daemons from AS and your command line are compatible
&lt;a class="heading-anchor" href="#--also-make-sure-the-daemons-from-as-and-your-command-line-are-compatible" aria-label="Link to ☝️ also make sure the daemons from AS and your command line are compatible"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Well almost. You also have to make sure you&amp;rsquo;re using the same JDK otherwise the gradle daemons will be incompatible.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# you have sdkman installed already&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sdk install java 8.0.202-zulu &lt;span style="color:#75715e"&gt;# use java 8 preferably&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sdk default java 8.0.202-zulu
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sdk install kotlin &lt;span style="color:#75715e"&gt;# cause why not&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now point Android Studio to use this jdk like so:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://kau.sh/images/content/as-same-jdk.png" alt="Android Studio Project Settings &amp;gt; SDK Location"&gt;&lt;/p&gt;
&lt;p&gt;💥 now we&amp;rsquo;re in business.&lt;/p&gt;
&lt;h1 id="disable-any-useless-plugins-or-add-ons-that-you-dont-need"&gt;
Disable any useless plugins or add-ons that you don&amp;rsquo;t need
&lt;a class="heading-anchor" href="#disable-any-useless-plugins-or-add-ons-that-you-dont-need" aria-label="Link to Disable any useless plugins or add-ons that you don’t need"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;&lt;img src="https://kau.sh/images/content/as-plugins-disabled.png" alt="Preference &amp;gt; Plugins &amp;gt; Installed"&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t get carried away and disable &lt;em&gt;everything&lt;/em&gt; here. It will hose your Android Studio. I know this cause I sure as hell tried.&lt;/p&gt;
&lt;p&gt;The only plugins I have enabled are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(Downloaded) IdeaVim&lt;/li&gt;
&lt;li&gt;Android APK Suport&lt;/li&gt;
&lt;li&gt;Android NDK Support&lt;/li&gt;
&lt;li&gt;Git Integration (cause i like Intellij&amp;rsquo;s Differ)&lt;/li&gt;
&lt;li&gt;Gradle&lt;/li&gt;
&lt;li&gt;Groovy&lt;/li&gt;
&lt;li&gt;Il8n for Java&lt;/li&gt;
&lt;li&gt;Intellij Configuration Script&lt;/li&gt;
&lt;li&gt;IntelliLang&lt;/li&gt;
&lt;li&gt;Java Bytecode Decompiler&lt;/li&gt;
&lt;li&gt;JUnit&lt;/li&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;Properties Support&lt;/li&gt;
&lt;li&gt;Smali Support&lt;/li&gt;
&lt;li&gt;YAML&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything else is disabled. &lt;a href="https://www.reddit.com/r/androiddev/comments/7sxhig/android_studio_slower_when_using_kotlin/dt88pgn/"&gt;This crony from Bob&amp;rsquo;s Discount Action Bars&lt;/a&gt; apparently knows a thing or two about Android.&lt;/p&gt;
&lt;h1 id="tweak-your-studiovmoptions-file"&gt;
Tweak your &lt;code&gt;studio.vmoptions&lt;/code&gt; file
&lt;a class="heading-anchor" href="#tweak-your-studiovmoptions-file" aria-label="Link to Tweak your studio.vmoptions file"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;The official &lt;a href="https://developer.android.com/studio/intro/studio-config.html"&gt;developer docs&lt;/a&gt; talk about configuring this properly.&lt;/p&gt;
&lt;p&gt;tl;dr: in Android Studio head to &lt;em&gt;&amp;ldquo;Help &amp;gt; Edit Custom VM Options&amp;hellip;&amp;rdquo;&lt;/em&gt; and change it to the below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#-Xms256m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#-Xmx2048m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-XX:ReservedCodeCacheSize&lt;span style="color:#f92672"&gt;=&lt;/span&gt;240m
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-XX:+UseCompressedOops
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Dfile.encoding&lt;span style="color:#f92672"&gt;=&lt;/span&gt;UTF-8
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-XX:+UseConcMarkSweepGC
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-XX:SoftRefLRUPolicyMSPerMB&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Dsun.io.useCanonCaches&lt;span style="color:#f92672"&gt;=&lt;/span&gt;false
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Djava.net.preferIPv4Stack&lt;span style="color:#f92672"&gt;=&lt;/span&gt;true
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Djdk.http.auth.tunneling.disabledSchemes&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Djna.nosys&lt;span style="color:#f92672"&gt;=&lt;/span&gt;true
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Djna.boot.library.path&lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-da
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Xverify:none
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-XX:ErrorFile&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$USER_HOME/java_error_in_studio_%p.log
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-XX:HeapDumpPath&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$USER_HOME/java_error_in_studio.hprof
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ###############################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# custom settings from https://github.com/artem-zinnatullin/AndroidStudio-VM-Options/blob/master/studio.vmoptions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ###############################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Runs JVM in Server mode with more optimizations and resources usage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# It may slow down the startup, but if you usually keep IDE running for few hours/days&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# JVM may profile and optimize IDE better. Feel free to remove this flag.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Sets the initial size of the heap, default value is 256m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Xms1G
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Max size of the memory allocation pool, default value is 1280m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-Xmx2G
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Sets the size of the allocated class metadata space that will trigger a GC the first time it is exceeded, default max value is 350m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-XX:MetaspaceSize&lt;span style="color:#f92672"&gt;=&lt;/span&gt;512m
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Anything else you&amp;rsquo;ve come across that&amp;rsquo;s helped a lot? &lt;a href="https://twitter.com/kaushikgopal/status/1163684028651732995"&gt;Hit me up on Twitter&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="updates-since-my-post-was-originally-published"&gt;
Updates since my post was originally published:
&lt;a class="heading-anchor" href="#updates-since-my-post-was-originally-published" aria-label="Link to Updates since my post was originally published:"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/TheSNAKY/status/1163703431237918720?s=20"&gt;@TheSNAKY&lt;/a&gt; pointed me to an easier way to get to the Edit VM options.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/matthewcmckenna/status/1163834088509386754?s=20"&gt;@matthewcmckenna&lt;/a&gt; reminded me that using sdk man, using the &lt;code&gt;/current&lt;/code&gt; path is better as you upgrade versions. I&amp;rsquo;ve changed the commands here to mark the default installation and then just point to that within the Android Studio screenshots&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="useful-resources-and-reference-links"&gt;
Useful resources and reference links:
&lt;a class="heading-anchor" href="#useful-resources-and-reference-links" aria-label="Link to Useful resources and reference links:"&gt;##&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@mydogtom/tip-reduce-the-number-of-gradle-daemon-instances-by-using-local-distribution-56f645cf2c97"&gt;Tip: Use local Gradle distribution instead of wrapper&lt;/a&gt; and &lt;a href="https://medium.com/@mydogtom/tip-how-to-reuse-gradle-daemon-between-android-studio-and-terminal-df5232d63f38"&gt;Tip: How to reuse Gradle daemon between Android Studio and terminal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@championswimmer/bringing-android-app-build-times-down-by-95-at-zomato-a505d938e9b8"&gt;Bringing Android app build times down by 95% at Zomato&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><guid>https://kau.sh/blog/android-studio-slow-as-fxxx/</guid><pubDate>Mon, 19 Aug 2019 07:00:00 GMT</pubDate></item><item><title>
Use paper towels more efficiently - shake and fold</title><link>https://kau.sh/blog/use-paper-towels-more-efficiently-shake-and-fold/</link><description>
&lt;p&gt;I&amp;rsquo;m a little troubled that I love these kind of lifehack videos.&lt;/p&gt;</description><guid>https://kau.sh/blog/use-paper-towels-more-efficiently-shake-and-fold/</guid><pubDate>Fri, 04 May 2012 07:00:00 GMT</pubDate></item></channel></rss>