All posts

52 posts across 9 years

2025

7 posts
Post illustration
emacs

Building Complex UIs in Emacs: Lessons from Three Approaches

Complex Emacs UIs are hard - multiple data sources, cascading updates, cursor management. I tried three approaches to the same interface: imperative rendering, widget.el with zones, and declarative components. Here's what I learned, and why I ended up writing a 2.5k line library.

Post illustration
emacs

The Emacs Widget Library: A Critique and Case Study

A deep dive into Emacs's widget library: what it does well, where it falls apart, and a step-by-step case study of building a table widget with editable cells. Includes working code and hard-won lessons about state management, layout hacks, and cursor position preservation.

nix

Why I ditched Nix after ~4 years

After using Nix, nix-darwin, and home-manager for 4-5 years, I've finally switched back to Homebrew and bash scripts. Here's why the promise of reproducibility didn't hold up on macOS, and how freeing 80GB of disk space was the final push I needed.

Post illustration
emacs-plus

emacs-plus: Emacs Client.app

After fixing PATH injection on macOS 15, I'm dusting off a year-old feature: proper Finder integration for emacsclient. Using AppleScript instead of shell scripts, Emacs Client.app now handles file opening from Finder, drag-and-drop, and auto-starts the daemon. With one cosmetic icon issue that needs your help to solve.

blog

Fresh Coat of Paint: Redesigning d12frosted.io

A complete visual overhaul of this site—migrating from Hakyll to Next.js, adopting a brutalist + jRPG aesthetic, and upgrading to Tailwind CSS v4.1. Sharp corners, bold colors, and way less fighting with build systems.

2022

5 posts
Post illustration
emacs

Vulpea v0.3

Announcing Vulpea v0.3, with major performance improvements for note querying operations. The release introduces a materialised view table that provides a 4.5x speed boost for general queries, plus specialised query functions that can be up to 150x faster in certain scenarios. Whilst write operations take a small hit, the trade-off is worth it for large note collections. I've also added several quality-of-life improvements like better metadata handling and new tag utility functions.

Post illustration
emacs-plus

emacs-plus: PATH injection

Sharing how I improved PATH handling in Emacs+ to solve a common pain point. By injecting the user's PATH into Emacs.app during build, users now get the expected environment variables when launching Emacs from anywhere on macOS. This change also simplifies native-comp configuration and helps avoid common compilation issues. Whilst it's not as dynamic as exec-path-from-shell, it provides a solid out-of-the-box experience for Emacs+ users.

Post illustration
emacs-plus

emacs-plus: stats

Sharing some analytics insights from Emacs Plus and how they'll influence future maintenance. Looking at installation data, Emacs 28 is currently the most popular version, and features like native-comp and xwidgets are heavily used. I'm considering deprecating some rarely-used options whilst making it easier to enable simple build flags. For icons, modern-doom3, nobu417-big-sur, and spacemacs lead in popularity. Any major changes will be well-communicated to avoid disrupting users' workflows.

Post illustration
yabai

Automatic setup of spaces with yabai

Sharing my yabai configuration for automatically setting up workspaces in macOS. I walk through how to create a consistent set of labelled spaces, clean up extras, and automatically move applications to specific workspaces on startup. Whilst tiling window managers aren't for everyone, this setup helps maintain an organised workflow by ensuring applications always land in their designated spaces.

blog

War and World

A personal note explaining that whilst I'll be less available due to the war in Ukraine, projects will continue—though help from the community would be welcome.

2021

8 posts
Post illustration
emacs

Path to org-roam v2

Migrating from org-roam v1 to v2—covering mandatory IDs, improved note structure, enhanced database queries, and the transition from file-based to ID-based linking, with migration scripts and lessons learned.

Post illustration
emacs

Fixing PATH in fish with nix-darwin

Fixing PATH order issues when using Fish shell with nix-darwin—Fish's path_helper reimplementation was moving .nix-profile/bin to the end, preventing nix packages from overriding system binaries. Solution: preserve original PATH and restore order after Fish initialisation.

Post illustration
emacs

Task management with org-roam Vol. 7: Capture

Streamlining task capture in org-roam with dedicated inbox files per machine, processing via org-agenda, and dynamic capture templates that automatically place one-on-one meeting notes in the correct person's file.

Post illustration
emacs

Project management tool for Emacs packages

Comparing build tools for Emacs packages—makem.sh for simplicity, cask for robustness, and eldev for extensibility—with observations on when each tool suits different project needs.

Post illustration
emacs

Towards future-safe emacs.d

Making Emacs configurations maintainable with eldev, straight.el, and structured init/lib/config files—achieving fast startup whilst enabling proper byte compilation, linting with elisp-lint, and testing with buttercup.

Post illustration
emacs

Retries with straight.el

Handling network instability when updating Emacs packages with straight.el by creating a retry wrapper using advice-add to automatically retry failed network operations.

2020

10 posts
Post illustration
emacs

Task management with org-roam Vol. 3: FILETAGS

Managing person-related tasks in org-roam using filetags to automatically tag all tasks (like @FrodoBaggins), maintaining tag inheritance whilst moving to individual notes.

Post illustration
emacs

Task management with org-roam Vol. 2: Categories

Fixing category display in org-roam agenda views by showing meaningful categories based on note titles instead of file IDs, with automatic extraction and formatting for clean, readable results.

Post illustration
emacs

Task management with org-roam Vol. 1: Path to Roam

How to organize tasks and projects in org-roam whilst maintaining compatibility with org-mode's agenda features. Implementing a familiar structure of tasks, projects, and meta-projects across multiple files.

Post illustration
emacs

Org-roam tags

Functions for managing tags in org-roam notes with completion support. Whilst this functionality is now part of org-roam v2, the code demonstrates how to extend org-roam and work with its database.

Post illustration
emacs

Emacs: moving to beginning of line

Custom Emacs functions for smarter line navigation that jump to meaningful content before the actual line start. Includes an enhanced org-mode version that handles headlines, TODO items, and list bullets intelligently—no external packages required.

Post illustration
haskell

Readings Vol. I: precondition encoding

Exploring different approaches to encoding preconditions in Haskell libraries, from simple Maybe types to sophisticated type-level guarantees. Drawing on insights from Alexis King's "Parse, don't validate" and Matt Noonan's "Ghosts of Departed Proofs", learn how to make illegal states unrepresentable.

Post illustration
haskell

Predicate composition

Exploring predicate composition in Haskell through multiple implementation approaches—from simple operators to Semigroup instances and coercion. Learn how to create elegant abstractions without runtime penalties by leveraging GHC's optimisation capabilities, complete with Core dumps and benchmarks.

Post illustration
emacs-plus

emacs-plus: current state

Status update on emacs-plus: improvements to CI/CD with GitHub Workflows, better patch management, and thoughts on simplifying build options whilst maintaining experimental features.

Post illustration
haskell

env-extra v1.0.0.0

Introducing env-extra, a small Haskell library that improves environment variable handling with Text support, flexible return types, and better error handling—reducing boilerplate from System.Environment.

2019

3 posts
Post illustration
emacs

flyspell-correct v0.6

Announcing flyspell-correct 0.6 with a new avy-menu interface, fixed point movements, lexical binding, and various improvements. Special thanks to @clemera and @Ergus for their contributions!

Post illustration
emacs

Emacs: reusing window for helpful buffers

How to make the helpful package reuse windows more sensibly in Emacs by customizing helpful-switch-buffer-function to keep your code visible whilst browsing documentation.

shell

Asking for input in Bash

Learn how to create a reusable 'ask' function in Bash that handles both required and optional user inputs with default values. Discover why bash's indirection and declare features are safer alternatives to eval for variable manipulation.

2018

5 posts
shell

Revisiting Eru

Introducing Eru.sh, my system bootstrapping script that sets up my development environment across different machines. Learn how I use Bash patterns like mapping over files and handling optional themes to make the code more maintainable, plus how to avoid eval whilst still achieving dynamic variable handling.

Post illustration
emacs

Equality of booleans in Emacs

Exploring the quirky world of booleans in Emacs Lisp—or rather, the lack of them! Since everything is either nil (the empty list) or some form of "true", comparing boolean values gets interesting. Learn different approaches using if/when, not, and xor to handle boolean comparisons properly.

shell

High quality GIF from video

Learn how to create high-quality GIFs from video using FFmpeg's custom palette generation. I share my 'gifify' script that automates the process, with options for FPS, scaling, and compression, plus visual examples comparing default vs custom palettes.

Post illustration
emacs

flyspell-correct v0.5

Announcing flyspell-correct 0.5 with rapid mode for fixing multiple words in one run, function renames, improved skipping behaviour, and test coverage.

shell

Random bytes generation with OpenSSL

A quick tip for generating high-entropy random bytes using OpenSSL's rand command. Learn how to use hex or base64 encoding to create valid random strings for passwords, and how to handle the output length when encoding changes the byte count.

2017

5 posts
Post illustration
emacs

Structure templates in Org mode

Discover Org mode's built-in structure templates that make inserting source blocks and other structural elements effortless. Learn how to use C-c C-, for modern template insertion or enable the legacy Easy Template system with <s<TAB> for quick shortcuts.

applescript

AppleScript and the GitHub API

Building a GitHub API client in AppleScript for OmniFocus integration. The script handles authentication and data extraction, though it has some efficiency limitations when fetching multiple values.

Post illustration
fish

Fish: notify me when you finish

A simple Fish shell hack to help you stay focused: get notified when long-running commands complete instead of getting distracted whilst waiting. Learn how to use Fish's CMD_DURATION variable to detect lengthy commands and send notifications when they finish.

git

Git: conditional configurations

Exploring Git's conditional includes feature and comparing it to my git-config-manager tool—whilst the native solution elegantly handles many use cases, there's still room for unique features.

blog

Deep in the black bashic

A humorous reflection on yak shaving: how wanting to write a blog post led me down a rabbit hole of infrastructure improvements—from EC2 to S3, Hakyll to Docker, and everything in between. Sometimes the journey is more interesting than the destination.

2016

6 posts
Post illustration
emacs

Being an org-mode addict

A personal reflection on my love-hate relationship with org-mode. Exploring how this deceptively simple outliner keeps drawing me back in, gradually imposing more complex features upon myself, whilst remaining an essential tool for organising my life.

shell

Errors in shell scripts

Learn how to write robust shell scripts that handle errors gracefully. This practical guide covers exit-on-error mode (set -e), signal traps for cleanup operations, and best practices for preventing corrupted states when commands fail.

Post illustration
emacs

flyspell-correct v0.1

Announcing flyspell-correct v0.1, featuring a complete package restructuring into separate core and interface modules, improved dependency management, and a new function for backwards spell-checking correction.

Post illustration
emacs

Emacs and Composability

A defence of Emacs' extensibility philosophy in response to discussions about Vim's composability. Exploring how Emacs' flexible architecture allows the community to implement any feature they value—including composability itself—whilst offering multiple paths to customisation.

Post illustration
emacs

flyspell-correct

Introducing flyspell-correct, a unified Emacs package that brings distraction-free spell-checking correction to your favourite completion framework. Learn how to correct misspelt words without leaving your current position, implement custom interfaces, and use rapid mode to fix multiple mistakes efficiently.

2015

3 posts
Post illustration
haskell

Cabal and executables

A historical look at solving Cabal Hell when installing Haskell executables. Learn how to use Cabal sandboxes to isolate dependencies and automate the process with custom Fish shell functions. Note: Stack and Nix-style builds have since made this approach obsolete.

Post illustration
fish

Make the Fish fly

A comprehensive review of the Fish shell after switching from Zsh. Discover how Fish's blazingly fast autocompletion, man page parsing, and sensible defaults provide an excellent out-of-the-box experience, plus the trade-offs you should consider regarding POSIX compatibility.

Post illustration
haskell

CanonicalPath v0.3.0.0

A summary of the third major release of CanonicalPath library, highlighting API changes, performance improvements, and enhanced testing infrastructure while maintaining compatibility with major Haskell package repositories.