zsh: add zoxide/bat/delta, starship prompt config, extra history options; rewrite README

Bootstrap (zshrc-bootstrap.zsh):
- Add bat and zoxide to the cross-distro install loop
- Add git-delta install block (package is 'git-delta' on every PM but
  binary is 'delta', mirroring the starship/lazydocker pattern)
- Debian/Ubuntu compat: symlink batcat->bat and fdfind->fd into
  ~/.local/bin so zshrc integrations work under both names
- Bump ZSHRC_BOOTSTRAP_VERSION 2 -> 3 so existing machines re-run the
  bootstrap and auto-install the new tools

zshrc:
- Add setopts HIST_VERIFY, EXTENDED_HISTORY, AUTO_PUSHD,
  PUSHD_IGNORE_DUPS, PUSHD_SILENT
- Self-configuring tool integrations (all behind command -v guards):
  - zoxide: eval $(zoxide init zsh) for frecent 'z'/'zi' dir jumping
  - bat: alias cat->bat, BAT_THEME, colored MANPAGER via bat
  - delta: GIT_PAGER=delta for prettier git diff/log/show
- Extend the interactive auto-update block to also sync starship.toml
  to ~/.config/starship.toml (overwrite-if-changed, validated the
  same way as zshrc); keep the reproducible/self-configuring design
- Inverted hyperlink fix already landed in prior commit; no change
  here

starship.toml (new):
- Two-line prompt: directory + git status + cmd duration on line 1,
  arrow (red on error) on line 2; Nerd Font symbols, SSH host/user,
  Python/Node/Rust/Go/Java/Docker context blocks
- Validated clean with starship 1.21.1 (uses [nodejs], not [node])

README.md:
- Full rewrite: documents the design philosophy, all files, deps,
  integrations, history options, aliases, keybindings, the eza
  hyperlink workaround rationale, auto-update behavior, per-machine
  overrides, env vars, and helper functions
This commit is contained in:
2026-07-29 11:30:49 -04:00
parent c4a804e760
commit 10caebad29
4 changed files with 294 additions and 11 deletions
+121 -6
View File
@@ -1,12 +1,127 @@
# 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
### `zshrc`
Main Zsh configuration file. Sets up Oh My Zsh, plugins (git, sudo, eza, fzf, starship, etc.), history options, aliases, and auto-updates itself from a remote source. Before replacing `~/.zshrc`, the downloaded file is validated with `zsh -n` to ensure it's syntactically valid — this prevents error pages or corrupted content from breaking the shell. Also bootstraps tmux config and runs a fastfetch system info display on interactive shells.
| File | Description |
|------|-------------|
| [`zshrc`](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`](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.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.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. |
### `zshrc-bootstrap.zsh`
One-shot setup script executed by `zshrc`. Installs missing dependencies (starship, lazydocker, fastfetch, eza, fzf, etc.) via the system package manager (brew, apt, dnf, pacman) or cargo, clones Oh My Zsh and custom plugins (zsh-autosuggestions, fast-syntax-highlighting, fzf-tab). Runs only when the bootstrap version changes.
## Getting Started
### `tmux.conf`
Tmux configuration with GitHub Dark theming, Nerd Font auto-install, TPM plugin manager, pane/window keybindings (Vim-style navigation with `h/j/k/l`), status bar showing session info, battery, online status, and a built-in cheatsheet (bound to `prefix + ?`).
Point `~/.zshrc` at the remote `zshrc`:
```bash
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:
```bash
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: `batcat``bat`, `fdfind``fd` (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`):
- **zoxide** — `z <substring>` jumps to frecency-ranked dirs; `zi` opens the fzf picker. `cd` still works.
- **bat** — `alias cat='bat'`, `BAT_THEME=Monokai Extended`, and `MANPAGER` set so `man` pages are colored and paginated by bat.
- **delta** — `GIT_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) |
## Eza Hyperlinks — Implementation Note
`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
```bash
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
```