Files
scripts/zsh
jeremy 9343715696 zsh: print a user-facing banner when the bootstrap fires
The bootstrap silently installs tools for ~30s+ on a version bump or
first login, which looked like an unexplained hang. Now prints a
banner explaining what is happening, that it may take a minute, and
that subsequent runs are a no-op. The box is built dynamically so the
right edge stays aligned regardless of the version string length.
Also clarifies the trigger comment in zshrc.
2026-07-29 11:35:43 -04:00
..

Zsh Config

A reproducible, self-configuring Zsh setup managed from a remote git repo. The zshrc auto-updates itself and the Starship prompt config on every interactive shell start, and a versioned bootstrap script installs all missing dependencies across distros. Drop ~/.zshrc in place once and every machine stays in sync automatically.

Design

  • Reproducible — one zshrc drives an identical environment across every machine and distro.
  • Self-configuring — tool integrations are guarded by command -v, so the shell works degraded-but-fine when a tool is absent, and lights up automatically once the bootstrap installs it.
  • Self-updating — on each interactive shell start, zshrc and starship.toml are re-pulled from the repo and applied if changed (downloaded files are validated with zsh -n before replacing anything, so a 502 error page or corrupted content can't break the shell).
  • Network-resilient — all remote calls use --fail + --connect-timeout/--max-time, so an unreachable server silently no-ops instead of hanging the shell.

Files

File Description
zshrc Main config. Path setup, history options, oh-my-zsh + plugins, eza theme, tool integrations, aliases, and the auto-update logic. Sources ~/.zshrc.local at the end for per-machine overrides.
zshrc-bootstrap.zsh One-shot setup script run by zshrc when the bootstrap version changes. Installs all dependencies across distros and clones oh-my-zsh + custom plugins.
starship.toml Starship prompt config — two-line prompt with directory, git status, command duration, Nerd Font symbols, and an error indicator. Synced to ~/.config/starship.toml by the auto-update logic.
tmux.conf Tmux config with GitHub Dark theming, Vim-style pane navigation (h/j/k/l), TPM plugin manager, Nerd Font auto-install, and a built-in cheatsheet (prefix + ?). Installed to ~/.config/tmux/tmux.conf on first shell start.

Getting Started

Point ~/.zshrc at the remote zshrc:

curl -fsSL https://git.jeremymcclure.com/jeremy/scripts/raw/branch/master/zsh/zshrc -o ~/.zshrc && exec zsh

On first start, zshrc bootstraps missing dependencies (oh-my-zsh, plugins, and all CLI tools below) over the next shell starts. To force a re-bootstrap (e.g., after adding new tool installs to the bootstrap script), the bootstrap version is bumped in zshrc and every machine re-runs it automatically — or run manually:

BOOTSTRAP=true exec zsh

Dependencies

All installed automatically by the bootstrap across brew / apt / dnf / pacman / cargo:

Tool Purpose
starship Prompt (configured via starship.toml)
fzf Fuzzy finder — powers fzf-tab completion and zi
eza ls replacement with icons, git status, hyperlinks
bat cat replacement + colored man pages
zoxide Frecency directory jumping (z, zi)
git-delta Pretty git diff/log/show pager
fastfetch System info on shell start
lazydocker TUI for Docker
rsync / tmux / git Core utilities

Debian/Ubuntu renames handled: batcatbat, fdfindfd (symlinked into ~/.local/bin).

Oh-My-Zsh Plugins

git, sudo, extract, eza, history, kitty, docker, docker-compose, archlinux, encode64, universalarchive, zsh-autosuggestions, fast-syntax-highlighting, fzf, fzf-tab, systemd, vscode, rsync, starship.

Tool Integrations

Each is enabled only when the binary is present (command -v):

  • zoxidez <substring> jumps to frecency-ranked dirs; zi opens the fzf picker. cd still works.
  • batalias cat='bat', BAT_THEME=Monokai Extended, and MANPAGER set so man pages are colored and paginated by bat.
  • deltaGIT_PAGER=delta so git diff/log/show render side-by-side with syntax highlighting. (Not aliased to diff — delta is a pager reading diff input on stdin, not a diff a b replacement.)

History & Shell Options

SHARE_HISTORY, HIST_IGNORE_DUPS, HIST_IGNORE_ALL_DUPS, HIST_REDUCE_BLANKS, HIST_FCNTL_LOCK, HIST_VERIFY, EXTENDED_HISTORY, AUTO_CD, AUTO_LIST, INTERACTIVE_COMMENTS, AUTO_PUSHD, PUSHD_IGNORE_DUPS, PUSHD_SILENT.

AUTO_PUSHD maintains an automatic directory stack, so cd -<TAB> and dirs let you navigate recent locations without pushd/popd muscle memory.

Aliases

Alias Action
c clear
q exit
open-ports ss -tulpn | grep LISTEN
nbstat Netbird peer status as a TSV table
yeet yay -Rcs (remove + deps + config on Arch)

Keybindings

Shortcut Action
Ctrl+R fzf history search (via fzf plugin)
Ctrl+T fzf file finder
Alt+C fzf cd
Tab fzf-tab completion menu
Esc twice Toggle sudo prefix (via sudo plugin)

zshrc does not set the oh-my-zsh eza plugin's hyperlink zstyle. The plugin emits a bare --hyperlink flag, which eza (clap) treats as taking the next token as its optional value — so la / fails with invalid value '/'. Instead, after oh-my-zsh loads, the aliases are rewritten to append the glued --hyperlink=always form, which can't eat a following path argument. Hyperlinks stay on and paths keep working.

Auto-Update Behavior

On every interactive shell start:

  1. zshrc — re-downloaded, validated with zsh -n, and applied via exec zsh only if it differs from ~/.zshrc.
  2. starship.toml — re-downloaded and moved to ~/.config/starship.toml if changed (applied live on the next prompt render; no shell reload needed).
  3. tmux.conf — downloaded once on first shell start if ~/.config/tmux/tmux.conf and ~/.config/byobu/.tmux.conf are both absent.
  4. bootstrap — runs (zshrc-bootstrap.zsh) when ZSHRC_BOOTSTRAP_VERSION in zshrc doesn't match ~/.config/zsh/.bootstrapped.

All downloads use --fail so a 502/HTML error page is never written over a working config, and --connect-timeout/--max-time so an unreachable server never hangs startup.

Per-Machine Overrides

~/.zshrc.local is sourced at the very end of zshrc (created empty if missing). Put machine-specific aliases, env vars, or PATH additions there — they survive repo updates since zshrc doesn't manage that file.

Environment Variables

Variable Default Purpose
ZSHRC_GIT .../scripts/raw/branch/master/zsh/ Base URL for all remote config files
ZSHRC_BOOTSTRAP_VERSION 3 Bump to force a re-bootstrap on all machines
FFENABLED (unset → enabled) Set to false to disable the fastfetch system info on shell start
BAT_THEME Monokai Extended Override before the bat block to use a different bat theme
GIT_PAGER delta (when installed) Override to use a different git pager

Helper Functions

update_zshrc        # Manually re-pull and reload the zshrc
fix_btopbg          # Disable btop theme_background (workaround for transparency)
install_opencode    # Install the opencode CLI
BOOTSTRAP=true exec zsh   # Force a re-bootstrap