If you’ve used nvm (Node Version Manager) for any length of time, you’ve probably noticed the shell startup delay. On my machine, nvm adds roughly 300-500ms to every new terminal—enough to feel sluggish. The common workaround is lazy loading. oh-my-zsh even has built-in support for it: zstyle ':omz:plugins:nvm' lazy yes NVM_LAZY_LOAD = true This defers nvm initialization until…
Disclaimer: This post was written by Claude with my direction! We’re all in the midst of recalibrating our ethical compass when it comes to programming and writing with LLMs. Since this post is intended as a reference for future me, it felt okay that I was simply a collaborator and editor. This document describes a robust DNS configuration for Tailscale on Linux that provides: MagicDNS for…
Sometimes I want to run long jobs overnight on my laptop, or even charge my phone while the laptop is closed in my backpack (getting USB to have power when suspended is another longstanding problem). For quite a while, I tried different variations of gnome-session-inhibit and systemd-inhibit . But they never worked properly! Finally, I found this gem on the Arch Linux forum: Systemd-inhibit…
When running a command, it’s often useful to save output to a file while also displaying it on the terminal. The tee command handles this elegantly: ./my-script.sh | tee output.log But this only captures stdout. To also capture stderr, the traditional approach is: ./my-script.sh 2> & 1 | tee output.log I recently learned about the fancy shorthand operator |& , which does the same:…
I had uploaded a post marked with the current date to GitHub, which has an action set up to rebuild Hugo and post to GitHub’s static page hosting. The post didn’t show. I assumed it was because their server was in a different timezone (e.g. PST) and was interpreting the dates as such. But then I loaded up a local server with hugo server and the post was not listed there either! It…
Today, I was in the process of exporting a few batches of files from Google Photos. You select up to 500 photos or videos, hit “Download”, wait a minute or so (depending on the size), and your browser will start downloading the ZIP. These are fairly large files (around 8 GB each in my case), and I was just heading out the door, so I had to cancel a few of them. Later on, when I pulled…
As part of writing html_to_pdf.sh for programatically printing a webpage to PDF format, I encountered the problem of fonts appearing differently after having been output as PDF. Further investigation revealed the alpine-chrome Docker image did not have the fonts being used in the HTML document. A simple solution—replace /usr/share font directories in the Docker image with those of the host:…
The resume I used for the majority of my life is a relic from university times, when I joined the Computer Science co-op program and applied for oodles of internship placements. Back in the day, I designed the layout in Microsoft Word, with careful formatting constructed of tables, blank lines with font size 1, and painstakingly adjusted margins. Word ran great with wine, and I even had a shell…
After attempting many different ways of getting Magisk to run on Android emulators (including Waydroid and the like), the only way that worked is using the official emulator from Google, along with the instructions from the following Gist: tothi/magisk_ramdisk_patch_avd.sh Notes userdata.img needs to be recreated when changing size via the emulator -partition-size flag, so pick its size carefully!…
Google Photos has two methods of handling motion photos: If the photo was uploaded by an Android device, it will already be in Google’s custom format, which is essentially a JPEG file with a video file concatenated to the end. If the photo was uploaded by an iPhone, it will be stored as two separate files on Google servers: HEIC and MOV. When downloading motion photos and re-uploading them…
In larger applications, there is usually a CI/CD process, which tests, builds, and deploys new versions of the software. Smaller applications typically start out with a simpler solution. In this case, I have an application running in a screen session, and I want a git post-receive hook to automatically update its code and restart the process. Is it possible to write a one-line Bash wrapper which…
A typical post-receive hook for updating a target directory based on the most recent commit might look like this: #!/bin/bash export GIT_WORK_TREE = '../myproject' git checkout -f master However, this does not remove any untracked files or directories in ../myproject . When files are removed or renamed in later commits, their remnants will remain untouched in the deployment directory. How can we…
Match and exit This StackExchange question provides a snippet which runs a subprocess, saves its PID, and then ends the process when a certain output string is encountered in its output. sh -c 'echo '$$'; exec stdbuf -oL '$0' '$@'' my-program with its args | ( IFS = read -r pid && sed '/Was exported to:/q' && kill -s PIPE ' $pid ' ) Match and exit, with short-circuit I encountered a situation in…
I was recently working with some CSV files pulled from a Samsung Health dump. I wanted to run a few queries on the data in order to familiarize myself with their format and contents. SQL seemed like a natural choice, and it turns out there is a myriad of different ways to directly query CSV data with SQL. A few notes: The first line of the file is extraneous information that Samsung Health…
It turns out that using the Google Photos API is not particularly suited to organizing your photos collection. On the other hand, the API makes it easy to create a listing of all photos and albums in your collection. For the case of creating a simple file-based JSON database, I wanted a command-line driven solution, so I used photoslibrary1-cli . Authentication The photoslibrary1-cli documentation…
Beware: Google Photos API is not suitable for reorganizing your photo collection. From Google for Developers documentation : batchAddMediaItems : Note that you can only add media items that have been uploaded by your application to albums that your application has created. batchRemoveMediaItems : Note that you can only remove media items that your application has added to an album or that have…
After adding a motion photo into a shared album, Google Photos sometimes fails to show the triangular ▶ play button. Right from the horse’s mouth: Google Photos can be a bit buggy with Live Photos in shared albums - the best way I’ve found to combat this is to just upload to Google Photos first (don’t add them to a shared album just yet), wait a bit (can be anywhere between a few minutes to…
Lately, it’s almost impossible to open up Hacker News without encountering an article extolling the virtues of LLM-assisted programming. I wanted to give it a try—but I decided to start with something small. Problem definition Given an input array of 0’s and 1’s, produce an array where output[i] gives the consecutive count of input[i] up until position i . For example:…
In A brief foray into GNOME extension development , we looked at the general process of updating a GNOME extension to work on a newer version of GNOME. The most obvious development environment for working on GNOME extensions is an active GNOME session. But I encountered numerous pain points with this setup: Reloading extensions: This is possible in X by reloading gnome-shell with Alt+F2 and r ,…
I used to be an exclusive user of tiling window managers, namely: xmonad . When I converted over to the GNOME world, I tried all of the window tiling extensions and settled on the excellent PaperWM . But PaperWM, as with most GNOME extensions, struggled to keep up with the rapid pace of GNOME releases, and I was stuck on vanilla GNOME for some time. Recently, Arch pushed the GNOME 43 release, and,…