My personal shell settings, heavily customised and refined over the years.
| File | Description |
|---|---|
.shenv |
Shared env vars and PATH setup — sourced by all shells |
.zshenv |
Zsh: always loaded; sources .shenv for non-login shells |
.zprofile |
Zsh: login shell; sources .shenv |
.zshrc |
Zsh: interactive shell config, completions, prompt, keybindings |
.profile |
Bash: login shell; delegates to .bashrc and sets locale |
.bashrc |
Bash: interactive shell config, completions, prompt |
.aliases |
Shared aliases and shell functions (git, ls, cd, kubectl, etc.) |
.gitignore_global |
Global gitignore |
.gitconfig |
Git config (symlinked to ~/.gitconfig by setup.sh) |
.tmux.conf |
Tmux config |
.ghci / .ghc |
GHCi config |
alacritty.toml |
Alacritty terminal config |
.scripts/ |
Personal utility scripts (added to PATH by .shenv) |
zsh-completes/ |
Extra zsh completions (symlinked to ~/.zsh/zsh-completes/) |
Run setup.sh to symlink all dotfiles into ~/. It also:
- Links
config→~/.ssh/config(machine-specific, gitignored) - Links
alacritty.toml→~/.config/alacritty/alacritty.toml - Creates
~/.zsh/and linkszsh-completes/into it
Run brew-setup.sh on macOS to install packages via Homebrew.
| Context | Files loaded |
|---|---|
| Always | zshenv |
| Login only | zshenv → zprofile → zlogin |
| Interactive only | zshenv → zshrc |
| Login + Interactive | zshenv → zprofile → zshrc → zlogin |
Common contexts: a new tmux window or SSH session is login+interactive; a plain terminal tab is interactive only; running a script is neither.
Arch resets PATH after sourcing .zshenv, forcing PATH setup into .zprofile. To handle this without duplicating logic, .shenv is sourced from both .zshenv (non-login) and .zprofile (login). Zsh also sets typeset -U path to deduplicate PATH entries across nested/re-sourced shells; bash deduplicates manually via awk at the end of .shenv.
.gitconfig is symlinked to ~/.gitconfig by setup.sh.
Workflow settings:
pull.rebase = true— avoids accidental merge commits on pullrebase.autosquash = true— auto-appliesfixup!/squash!prefixesmerge.conflictstyle = zdiff3— shows common ancestor in conflict markersrerere.enabled = true— remembers conflict resolutions across repeated rebases
Diff: core.pager = delta routes all diff output through delta for syntax-highlighted, navigable diffs (n/N between hunks).
Large repo performance:
core.fsmonitor+core.untrackedCache— FSEvents-backed monitor sostatus/add/commitstop rescanning the whole tree.index.version = 4+index.skipHash— a leaner, faster index.fetch.writeCommitGraph— keeps the commit-graph fresh for fastlog/blame/merge-base;fetch.prunetidies deleted remote branches.
Per-repo operational levers for very large repos:
git maintenance start # prefetch + repack on a schedule
git clone --filter=blob:none <url> # partial clone
git sparse-checkout set --cone <dirs> # check out only what you needSourced conditionally from common install paths (Homebrew ARM/Intel, Arch, Debian):
- zsh-autosuggestions — Fish-like inline suggestions from history; right arrow or
Endto accept - zsh-syntax-highlighting — colours commands red/green as you type (sourced last, as required)
Key tools wired up in the config:
| Tool | Wired up in | Notes |
|---|---|---|
| bat | .shenv, .aliases |
MANPAGER for syntax-highlighted man pages; cat aliased to bat |
| fzf | .zshrc |
Fuzzy finder; uses fd for file listing and bat for previews |
| zoxide | .zshrc |
Smart cd; z <query> jumps to frecent dirs, zi for interactive selection |
| delta | gitconfig_template |
Pager for all git diff output |
| direnv | .zshrc |
Per-directory env var loading |
BSD-licensed. Written and maintained by David Terei.