Support either shell as the login shell via stow selection (merges the
bashed branch in). shell/ holds shared POSIX env + interactive config;
each shell loads its own rc natively.
- zsh: add .zshenv (sets ZDOTDIR+env early), rename rc -> .zshrc, add
login-only .zprofile (pyenv --path)
- bash: add ~/.bash_profile + ~/.bashrc stubs, .config/bash/{rc,prompt}
- shell: profile is POSIX env-only (no zsh-rc source); path rewritten
POSIX + idempotent (flat ~/.local/bin, no subdir recursion); new
interactive sources aliases/functions + pyenv shims
- drop dead shell/.zprofile symlink; move ZDOTDIR out of exports
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.7 KiB
My personal dotfiles
To be used with GNU stow.
Goal is a clean-as-possible home directory.
As much as possible in standard .config/, .local/ and so on.
Shell architecture (multi-shell)
The config supports both zsh and bash from one branch. Pick the login shell
by which package you stow; shell/ is always stowed. (There used to be a
separate bashed branch — retired; do not recreate it.)
Split by role:
shell/(shared) — POSIX, shell-agnostic.exports,path— environment.pathis idempotent (safe to source twice).aliases,functions— interactive bits, POSIX-safe.interactive— sourcesaliases/functions/extra+ pyenv shims. Loaded by each shell's own rc (brace expansion OK; only zsh/bash source it).profile— POSIX login env only (no brace expansion, no rc source).~/.profilesymlinks to it.
zsh/—~/.zshenv(setsZDOTDIR+env, runs for every zsh),$ZDOTDIR/.zshrc(interactive, sourcesshell/interactive),$ZDOTDIR/.zprofile(login-only, pyenv--path).bash/—~/.bash_profile(login → sources~/.bashrc+ pyenv--path),~/.bashrc(sources~/.profilefor env, then~/.config/bash/rc),~/.config/bash/rc(interactive, sourcesshell/interactive+ bash bits),prompt.
Invariants worth keeping:
ZDOTDIRbelongs in~/.zshenvonly — it must be set before zsh reads any rc file, soexportsis too late.- Env must reach non-login interactive shells: zsh gets it via
.zshenv(always runs); bash gets it because.bashrcre-sources~/.profile(idempotent). Don't move env loading out of those two spots. - Prompts are necessarily per-shell (
%n@%Mvs\u@\h); keep them split.
Known issues / TODO (next session)
Remaining from the 2026-06-26 review (zsh/bash startup items already fixed):
-
Clean-home goal leaks:
psql/rc:HISTFILE ~/.psql_history-:DBNAMEwrites a dotfile to$HOME. Redirect under~/.cache.git/config:excludesfile = ~/.gitignore,attributesfile = ~/.gitattributes. Move to~/.config/git/{ignore,attributes}(git readsignorethere by default).
-
History dirs not created.
HISTFILEpoints at$XDG_CACHE_HOME/shell/history, but zsh/bash won'tmkdirthe parent, so history is silently dropped. Need a bootstrap/mkdir -p. (The python startup script already does its own mkdir.) -
Dead config. alias
f="$FILE"—$FILEis never set (empty alias);functionsfile is empty;git/configcarries macOS-only settings (trustctime,precomposeunicode, mac comments) — dead weight on Arch.bash/.config/bash/rcalso keeps Homebrew/macOS completion blocks (guarded, harmless, but droppable).