Your dotfiles are how you personalize your system. These are mine, forked from holman does dotfiles and highly modified (Thanks, Zach!).
Note: Unless you're me, you should probably fork and modify this prior to installing.
Run:
git clone https://github.com/cmpaul/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
script/bootstrap.shThis will symlink the appropriate files in .dotfiles to your home directory,
install Homebrew and the packages in homebrew/Brewfile, set macOS defaults,
and set up git with a GPG signing key. Everything is configured and tweaked
within ~/.dotfiles.
There's no need to install Homebrew yourself first — bootstrap does it. If
you did (or its installer told you to echo ... >> ~/.zprofile), skip those
instructions: zsh/zprofile.symlink already wires up brew shellenv, and
appending would either create a stray ~/.zprofile that conflicts with the
symlink at bootstrap time (choose overwrite if prompted) or dirty the repo
file through it.
To keep things fresh later, run ~/.dotfiles/bin/dot — it re-applies macOS
defaults (asks for sudo), updates Homebrew packages, and re-runs the topic
installers. The shell also offers to run it for you (with a y/N confirmation)
when opening a terminal if it hasn't run in 30+ days; declining snoozes the
offer for a day. Pass DOTFILES_SOFTWAREUPDATE=1 to also install macOS
software updates.
Everything's built around topic areas: zsh/, git/, homebrew/, mise/,
osx/, gnupg/, fonts/ (MesloLGS NF, the patched font powerlevel10k
needs), terminal/ (a Terminal.app profile using it, set as the default).
Special behaviors:
- bin/: added to
$PATH, so everything in it is available everywhere (including a set ofgit-*subcommands wired up as git aliases). - topic/*.symlink: symlinked into
$HOMEwith a leading dot when you runscript/bootstrap.sh(e.g.zsh/zshrc.symlink→~/.zshrc). - topic/install.sh: run by
script/start.sh(and therefore bybootstrap.shanddot) — used for one-time setup like the GPG agent.
Anything that shouldn't follow you to another machine goes in one of these.
They live in $HOME, never in the repo, and are picked up only when present.
The topic installers seed a commented-out stub for each one, so you don't have
to remember the filenames — which means bin/dot backfills them on machines
set up before a given override existed. Existing files are never touched.
Nothing here is ever committed.
~/.zshrc.local— machine-specific interactive shell config. Sourced last by~/.zshrc, so it can override anything the tracked config sets. Must not write to stdout (p10k instant prompt flags it).~/.localaliases— machine-specific aliases. Sourced after~/.aliases, so they win. Edit withlocalaliases.~/.zprofile.local— machine-specific login-shell environment: PATH entries and env vars needed in non-interactive login shells too (chmod 600).~/.secrets.conf.local— machine-specific 1Password mappings, read byload-secretsalongside the trackedzsh/secrets.conf(chmod 600). Holdsop://references only — see Secrets.~/.Brewfile.local— extra Homebrew packages, installed after the shared Brewfile.~/.gitconfig.local— generated by bootstrap (name, email, signing key); versioned asgit/gitconfig.local.symlinkbut gitignored.
Secrets are never written to disk, in the repo or out of it. They live in 1Password, and the config files hold only references to them:
OPENAI_API_KEY=op://Private/OpenAI API Key/credential
Shared mappings go in zsh/secrets.conf (tracked); machine-specific ones go in
~/.secrets.conf.local (untracked). load-secrets reads both, signs in to
1Password, and exports the values into the current shell. A padlock reminder
prints on new sessions while any mapped variable is still unset.
To add a secret: create the 1Password item, then add one line to whichever
mapping file fits. Don't put secret values in ~/.zprofile.local.
I want this to work for everyone; that means when you clone it down it should work for you even though you may not have some dependency installed. That said, I do use this as my dotfiles, so there's a good chance I may break something if I forget to make a check for a dependency.
If you're brand-new to the project and run into any blockers, please open an issue on this repository and I'd love to get it fixed for you!