My personal macOS setup. For those who no longer find spiritual enlightenment in the 47-click System Preferences pilgrimage after each reinstall.
The symlink architecture that makes this work:
~/dotfiles/
├── .config/ # Modern configs → symlinked to ~/.config/
│ ├── fish/ # Primary shell (vi mode, fzf, zoxide)
│ │ # Zsh config also kept for compatibility
│ ├── zed/ # Daily driver editor
│ ├── karabiner/ # Keyboard customization
│ ├── amethyst/ # Window management
│ └── linearmouse/ # Mouse settings
├── .vimrc, .zshrc, etc # Classic dotfiles → symlinked to ~/
├── .doom.d/ # Doom Emacs config
├── .hammerspoon/ # Hotkey automation
├── tools/ # Productivity scripts → on PATH directly
│ # Audio conversion, doc generation, game launchers, etc
├── scripts/
│ ├── symlink-setup.sh # Wires everything up
│ ├── macos-defaults.sh # System preferences automation
│ ├── vscode-sync.sh # Keeps VS Code settings in sync
│ └── fish-paths-reset.fish # Rebuilds PATH when fish won't let go
├── Brewfile # Every app and CLI tool
└── setup.sh # Orchestrates it all
Secrets, machine-specific paths and Claude config live in a second repo that isn't
this one and isn't on GitHub, cloned to ~/dotfiles-private. symlink-setup.sh
wires it up if it's there and shrugs if it isn't, so this repo stands alone on a
fresh machine — you just get no API keys with it.
Nothing sensitive is in here. That's the whole point of the split.
- macOS Defaults: Disables animations in favor of speed and responsiveness
- Key Repeat: Set to ludicrous speed for zooming around in vim
- Finder: Forces column view
- No More Accents: Disabled the accent menu that pops up when you hold a key
- Hammerspoon: Hotkeys for essentials like:
super+A: Toggling between AirPods and laptop speakers (because auto switching is finicky at best)super+D: Toggle dark mode
- Amethyst: Window management for keyboard-focused workflows
- Karabiner/LinearMouse: Input device customizations for maximum comfort (mouse acceleration, caps lock doubles as ESC/ctrl)
- Fish Shell: Primary shell with vi mode, better defaults than Zsh (which is kept for compatibility)
- Zed: The daily driver
- VS Code: Kept around because sometimes you need it
- Vim/Neovim: Vanilla is probably fine but the config lives on
- Doom Emacs: Glorified magit launcher, aka the best git client
-
Clone this thing:
git clone https://github.com/stephenkirk/dotfiles.git ~/dotfiles -
Run the script:
cd ~/dotfiles ./setup.sh
-
Go make coffee. Or tea. Or grab a beer. This will take a bit.
Peruse the Brewfile if you're curious about what I use daily. It's a mess, but it's my mess.
Fork it. Break it. Fix it. It's yours now.
Ergonomic Keyboard Remapping
Karabiner handles the magic:
- Caps Lock (tap) = ESC, (hold) = CTRL (no more pinky destruction)
- ESC (tap) = Caps Lock, (hold) = Hyper (Shift+Ctrl+Opt+Cmd combined into one super-modifier)
Hammerspoon then uses Hyper for system-wide hotkeys that won't conflict with anything:
Hyper+H: Show all available hotkeysHyper+A: Toggle between AirPods and speakersHyper+D: Toggle dark mode
Smart PR Review List
Get PRs awaiting your review as Markdown links, ready to paste — tools/to_review:
gh pr list -S "review-requested:@me" --json title,url,author \
--jq 'map("[\"@\(.author.login): \(.title)\"](\(.url))") | .[]'Kill All the Animations
macOS is faster when it's not busy being pretty:
defaults write -g NSWindowResizeTime -float 0.001
defaults write -g NSToolbarFullScreenAnimationDuration -float 0
defaults write com.apple.dock expose-animation-duration -float 0See scripts/macos-defaults.sh for the full list.