Skip to content
birkhoffleePublic

About

my platform-agnostic dotfiles

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Latest commit

 

History

998 Commits

Folders and files

Repository files navigation

dotfiles

Acquiring good taste comes through using various things, discarding the ones you don't like and keeping the ones you do. if you never try various things, you will not acquire good taste.

And what I mean by taste here is simply the honed ability to distinguish mediocrity from excellence. This will be highly subjective, and not everyone's taste will be the same, but that is the point, you should NOT have the same taste as someone else.

Question the status quo, experiment, break things, do this several times, do this everyday and keep doing it.

— If you don't tinker, you don't have taste

My nix-darwin and NixOS configuration.

My daily driver is macOS because I prefer the Apple desktop environment. There are also a NixOS homelab server (running as a Proxmox VM) and NixOS VM setups mainly for experiments.

Screenshot of fastfetch on M1 Pro running macOS Golden Gate

Overview

  • Nix flakes provide a reproducible, pin-exact configuration shared across all machines.
  • On macOS, nix-darwin manages system-level settings and packages declaratively.
  • home-manager manages the user environment (dotfiles, packages, shell) across both macOS and NixOS hosts.

Highlights

  • Terminal: Rex
  • Font: Berkeley Mono™ Typeface
  • General zsh configuration:
  • CLI apps of choice:
    • Editor: Helix
    • Shell History: Atuin
    • File Manager: Yazi (invoke with y for shell integration)
    • Directory Navigation: zoxide
    • fzf shell integration (config)
      • CTRL-T - Full-screen file picker (streamed from fd) with a file/directory preview; Tab to multi-select, CTRL-O to open the selection in $VISUAL
      • ALT-C - cd into the selected directory, with a tree preview
      • In any fzf: ? toggles the preview, ALT-↑/↓ pages through it
    • fzf-tab for fuzzy-searching zsh completion results, in the same Catppuccin theme, with context-aware previews:
      • Files and directories (cd, hx, bat, ls, mv, …): syntax-highlighted via lesspipe + bat, or an eza tree
      • git: delta diffs for add/diff/restore (untracked files show their contents), commits for show/checkout/log
      • man pages, docker (subcommand help, logs, images, inspect JSON), brew info, process details for kill, and systemctl status on Linux
      • Command names (tldr) and variable values (echo $<Tab>)
      • < / > switch between completion groups
    • Per-project environments: direnv + nix-direnv (cached devshells that survive GC)
  • Git:
  • Secrets: agenix, decrypted with an identity held in 1Password via age-plugin-1p, so no private key on disk
  • macOS: system and app preferences (Dock, Finder, keyboard, trackpad, Safari, third-party apps…) set declaratively via nix-darwin; GUI apps via Homebrew

Custom Shell Shortcuts & Functions

Keybindings

Custom Zsh keybindings are configured in home/modules/shell/keys.zsh.

This is designed to work with default Ghostty macOS keybindings, or the iTerm2 Natural Text Editing keymappings preset.

Keybinding Reference
Key Combo Description
Ctrl+U Delete everything to the left of the cursor
Ctrl+X then Delete Delete entire line to the left of cursor
Ctrl+B Jump to beginning of line
Alt+Q Push aside current command line to type a new one (re-inserted on next prompt)
Ctrl+X then Ctrl+_ Redo last undone edit
Ctrl+X then Ctrl+E Edit current command line in $EDITOR
Alt+V Show next key combo's terminal code and description
Alt+Shift+S Prefix current/previous command with sudo

Utility Functions

Shell functions are defined in home/modules/shell/functions.zsh.

A non-exhaustive list:

Video & Media
  • burnsrt <input.mp4> <input.srt> <output.mp4> - Burn SRT subtitles into MP4 video
  • shrinkvid <input> <output> [bitrate] - Compress video (uses hardware acceleration on macOS)
  • impaste > file.png - Output clipboard image data to stdout
  • favicon <input.png> - Generate multi-size favicon.ico from an image
  • dirtypdf <input.pdf> <output.pdf> - Apply scanner effect to a PDF
Development & Git
  • gg <repo-url> - Clone repo and cd into it
  • aic - Generate conventional commit message using LLMs from staged changes
  • e [file] - Edit file with $VISUAL, or open current directory if no argument
  • s <pattern> - Search in files and visualize with Delta
Directory & File Management
  • take <dir> - Create directory and cd into it (equivalent to mkdir -p && cd)
  • tt - Create and cd into a temporary directory
  • cdls <dir> - Change to directory and list its contents
  • decrypt_pdfs <password> - Decrypt all PDFs in current directory
Network & Diagnostics
  • t <host> - Traceroute with Trippy (auto-updates GeoIP database)
  • tu <host> - UDP traceroute with Trippy
  • https <domain> [port] - Show TLS certificate details (default port: 443)
  • ttfb <url> - Measure Time To First Byte with curl
  • listening [pattern] - List all processes listening on TCP ports
  • pingu <host> - Ping until success or cancelled
  • lip <ip> - Lookup IP address details
  • dns <domain> - Lookup IP address of domain's A record
Nix Utilities
  • nix-pkgdir <package> - Get the Nix store path for a package
  • nr <package> [args...] - Run a package from nixpkgs-unstable without installing
  • ns <pkg1> [pkg2...] - Start a shell with packages from nixpkgs-unstable

Usage Instructions

Commonly used commands in justfile
# Switch darwin configuration
just switch

# Updates all flake inputs
just update

# Updates one flake input
just update-input <flake-input-name>

# For more, run `just` to get all recipes.
Installation instructions on a new macOS machine without Nix installed

Make sure the username aligns to the one specified in flake.nix (ale).

Full Disk Access has to be enabled for the terminal app via System Settings > Privacy & Security > Full Disk Access to overcome Could not write domain com.apple.universalaccess; exiting when applying user defaults.

xcode-select --install

# Install Homebrew (manages GUI apps)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install 1Password and login manually so credentials are present
brew install --cask 1password

# Clone the dotfiles
mkdir $HOME/.config
git clone https://github.com/birkhofflee/dotfiles $HOME/.config/dotfiles

Install Determinate Nix using the macOS package, then:

# Temporarily mitigate 'too many open files' issue
# @see https://github.com/NixOS/nix/issues/6557
ulimit -n 4096

# Pre-seed GitHub's SSH host key so the private secrets input doesn't stall
mkdir ~/.ssh
ssh-keyscan -H github.com >> ~/.ssh/known_hosts

# Add the current user to trusted-users so --accept-flake-config is honoured,
# allowing Nix to use the binary caches declared in the flake's nixConfig.
echo "trusted-users = $USER" | sudo tee -a /etc/nix/nix.custom.conf

# Activate the configuration
nix run nixpkgs#nh -- darwin switch $HOME/.config/dotfiles --hostname AlexMBP --accept-flake-config
Applying the home config on a generic Linux host (e.g. WSL)

On a non-NixOS distro only the user environment is managed, via a standalone home-manager configuration: homeConfigurations."ale@wsl" in flake.nix. It assumes x86_64-linux and the username ale (home at /home/ale); copy the output and adjust system / currentSystemUser for other boxes.

Compared to the other hosts it leaves out agenix secrets and the 1Password and Ghostty modules, and doesn't manage ~/.ssh/id_ed25519.pub so the host can keep its own key pair.

Install Determinate Nix (on WSL2, enable systemd in /etc/wsl.conf first), then:

curl -fsSL https://install.determinate.systems/nix | sh -s -- install

# Pre-seed GitHub's SSH host key so the private secrets input doesn't stall
mkdir -p ~/.ssh
ssh-keyscan -H github.com >> ~/.ssh/known_hosts

# Add the current user to trusted-users so the flake's binary caches are honoured
# (otherwise e.g. Helix is compiled from source). Answer `y` to the trust prompts
# on the first switch.
echo "trusted-users = root $USER" | sudo tee -a /etc/nix/nix.custom.conf
sudo systemctl restart nix-daemon

# Activate the configuration
nix run nixpkgs#nh -- home switch github:birkhofflee/dotfiles -c ale@wsl --no-nom -- --refresh

# home-manager can't change the login shell outside NixOS
command -v zsh | sudo tee -a /etc/shells
chsh -s "$(command -v zsh)"

Afterwards, nh is installed by the config itself, so updates are just nh home switch github:birkhofflee/dotfiles -c ale@wsl --no-nom -- --refresh.

Notes:

  • --refresh makes Nix re-fetch the repo; otherwise a github: flake ref is cached for up to an hour and a freshly pushed commit is silently ignored.
  • --no-nom works around nix-output-monitor#320 (nom 2.2.0 can't parse Determinate Nix's newer log events). The fix is merged upstream but unreleased; drop the flag once nixpkgs ships a newer nom.
  • If activation fails with Existing file ... would be clobbered, move that file out of the way (or pass -b backup), after checking it isn't something the host needs.
Provisioning nixos-desktop-01 (NixOS desktop VM)

nixos-desktop-01 is a Proxmox KVM VM with GNOME DE. Remote desktop is provided by Gnome Remote Desktop on port 3389 (RDP).

List of RDP clients available on macOS

1. Build the VMA image

# Syncs working tree to nixos-server-01 and builds there (x86_64-linux).
just build-desktop-image

2. Upload to PVE (run on nixos-server-01)

rsync -avz /tmp/dotfiles-build/result/vzdump-qemu-nixos-desktop-01.vma.zst root@homelab-nuc:/var/lib/vz/dump/

3. Restore as VM on PVE

# SSH into homelab-nuc
# Assuming VM ID 201

# Stop the current VM
qm stop 201

# This creates (or replaces) VM 201 with our image.
# QEMU config is baked in. Starts the VM afterwards.
qmrestore /var/lib/vz/dump/vzdump-qemu-nixos-desktop-01.vma.zst 201 \
  --unique true \
  --storage local-lvm \
  --force \
  --start

--unique true is required — the image has a zeroed MAC address by default.

4. Connect via RDP

Once the VM is up, it should be connected to Tailscale automatically (if the authkey given was valid).

If RDP fails somehow:

  • RDP client-side config use redirection server name:i:1 may be required to connect.
  • On macOS, try to use Thincast Remote Desktop Client instead.
  • SSH to the VM and check status using sudo grdctl --system, ss -tlnp | grep 3389, sudo systemctl status gnome-rdp-setup gnome-remote-desktop

6. Apply config changes after provisioning

just switch-nixos-desktop

Articles

Here are some reads you might find interesting:

Some completions setups:

Acknowledgements

This project was heavily inspired by other open-source dotfiles. A non-exhaustive list:

Credits are given in the source code where applicable.

License

This project is released under the MIT License.

About

my platform-agnostic dotfiles

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Contributors

Languages