Skip to main content

· 16 min read

I wanted my email in local Maildir files — searchable, indexable, and accessible from the command line. The goal is a stack where mbsync handles IMAP sync, himalaya provides quick CLI access, and neomutt gives me a full TUI when I need it. Push notifications via IMAP IDLE keep it all near-instant.

I run two accounts through this setup — Fastmail (personal) and Google Workspace (work) — and adding more follows the same pattern.

· One min read

I have a global keyboard shortcut (⌥`) to mute my microphone on Zoom. I've done this several ways in the past but right now my solution is to send the mute keyboard shortcut (⌘⇧A) to the Zoom app via Keyboard Maestro.

Screenshot of Keyboard Maestro

Download Macro

Mute status in macOS Menubar

Using SwiftBar, I have a script which checks the mute status and displays it in my menubar. Screenshot of Swiftbar Zoom mute state icon Download Script

· 4 min read

When serving assets and attachments from Rails and ActiveStorage, a CDN is a great way to reduce load on your web server and speed up content delivery to your users.

Asset CDN

First, even if you're not using ActiveStorage, you'll want to set up a CDN to stand in front of your app. This will proxy requests for images, fonts, javascripts, and stylesheets that live in your app's repository.

The ideal setup here is to serve your assets from your app, set a high cache-expiration, and serve your assets through a CDN.

Setting up your Asset CDN

For a CDN, I recommend Amazon CloudFront. You'll want to create a web distribution which points at the root of your app. Heroku [has a good guide][2] on that.

· One min read

My main computer is my iMac. It seemed like every time I opened my MacBook Pro, it would show this screen:

MacBook Pro showing low battery full screen

So I researched a bit and fixed it. Here's what I did:

· 2 min read

I was looking for an outbound ping tool that I could run continuously on a secondary monitor or in the background so I could quickly troubleshoot internet outages or packet loss.

For example, when I'm in a video call, if the other person starts to have issues with audio/video, I can, with a glance, tell if it's me or not by looking for latency/packet loss amongst the hosts I'm pinging.

[ICMPUtil][1] is the best I've found. It's $6 [on the App Store][2].

Screenshot of ICMPUtil

· 2 min read

I've been searching for a solution to allow me to instantly search Google from anywhere on my Mac. My goal is to access the result I want as fast as possible.

My previous solution was to use the default fallback search in Alfred. I hit Option-Space typed my search and pressed Enter. This was pretty good. It would open Safari with my query's Google results. The page would take two seconds to load and then I'd have to figure out how to select the result I wanted.

Ideally, I'd just press 1, 2, 3, etc on my keyboard to launch the corresponding result. But the closest I could find was a vim-like browser plugin (such as Vimari) which gives all links a letter combination to type to navigate to it. Or Shortcat, which I use for navigating all macOS UI.1

This solution wasn't fast enough for me though. I wanted a more modal experience where I hop into an ephemeral search session.

· 2 min read

I wanted to log my internet's upload and download speeds over time. brew search speed turned up speedtest-cli which uses speedtest.net servers to measure what I was interested in.

Unfortunately it's a one time test and if you want it to repeat, you'll need to automate it. I chose a simple shell while loop to handle this for me1:

while; do
speedtest-cli --json --server $(
speedtest-cli --list |
grep -E "CenturyLink|Sprint|Enid|OneNet|Cox|Suddenlink" |
head -20 |
cut -f 1 -d ')' |
sort -R | head -1
) | tee -a speedtest-log.json
sleep 600
clear
done

This checks a random nearby server every 10 minutes.

· 2 min read

In certain scenarios, I've found it useful to use our production app's Read Replica as a source for manual testing. It's not something I'm reaching for often but there are definitely cases where our seed data just doesn't cut it.

Since it's a read replica, no writes can be made to it and I don't have to worry (too much) about harming production. You'll want to make sure any external user operations aren't configured to happen automatically (e.g. sending email, cropping avatars, etc).

Destroy

In order to assign a different DATABASE_URL to a review app, you'll need to destroy the postgres attachment on your review app. I knock this out by chaining some commands together:

· 3 min read

After running brakeman you'll get a report and, if there are new warnings, it will exit with a status code of "3". Typically, I only see two types of output from Brakeman. Either a large report where there are new warnings or a short report which is saying Brakeman is out of date.

I'll briefly explain resolving both.

Resolving New Warning(s) Detected

The long report.

Run brakeman -I to get an interactive console for ignoring warnings. It will analyze your code base and then prompt you for where to find the ignore file. I've always used the default location of config/brakeman.ignore, so I simply press Enter to accept the default.