Terminal & Shell — Ghostty, Starship, Zsh, Fish
Ghostty (GPU terminal), Starship (prompt), the Zsh + Fish setup with eza, fzf, zoxide, Atuin, and the four-plugin fish-like Zsh experience.
The terminal stack: a GPU terminal, a single prompt shared by both shells, and Zsh + Fish kept in lockstep so you can switch at any time.
Ghostty
GPU-accelerated terminal. Tokyo Night theme, JetBrains Mono Nerd Font, tabs, splits, clipboard.
brew install --cask ghostty
mkdir -p ~/.config/ghostty
ln -sf ~/dotfiles/ghostty/config ~/.config/ghostty/config | Feature | Value |
|---|---|
| Theme | Tokyo Night (built-in) |
| Font | JetBrains Mono Nerd Font · 13pt |
| Background | 95% opacity + blur radius 20 |
| Working dir | ~ on every new tab/window |
| Scrollback | 10 MB |
| Copy on select | Enabled |
Tabs
| Key | Action |
|---|---|
| ⌘ T | New tab |
| ⌘ W | Close tab / split |
⌘ ] / ⌘ [ | Next / previous tab |
| ⌘ 1–8 | Jump to tab |
| Ctrl + Tab | Next tab |
Splits
| Key | Action |
|---|---|
| ⌘ D | Split right |
| ⌘ ⇧ D | Split down |
| ⌘ ⌥ H/J/K/L | Navigate splits |
Inactive splits are dimmed (0.7 opacity), mouse-hover switches focus.
Power
| Key | Action |
|---|---|
| ⌘ ` | Toggle Quick Terminal — global Quake drop-down (works anywhere) |
| ⌘ ⇧ P | Command palette — fuzzy-search every Ghostty action |
⌘ ↑ / ⌘ ↓ | Jump to previous / next shell prompt |
| ⌘ ⇧ S | Dump current screen to a file and open in $EDITOR |
| ⌘ ⇧ Y | Dump current selection to a file and open in $EDITOR |
| ⌘ ⇧ R | Reload Ghostty config without restarting |
Notifications: any command that runs > 10s in an unfocused tab triggers a macOS notification on completion.
Misc
| Key | Action |
|---|---|
| ⌘ K | Clear screen |
| ⌘ ↩ | Toggle fullscreen |
⌘ = / ⌘ - | Font size up / down |
| ⌘ 0 | Reset font size |
| ⌘ N | New window |
| ⌘ , | Open config |
Option key acts as Alt (vim/fish Alt-bindings work). Cursor hides while typing.
Starship
Two-line bracket prompt with live tech-stack, git, command status, monorepo detection, and a dedicated Claude Code statusline. Tokyo Night palette throughout.
Prompt layout (illustrative):
╭─ ~/dots/sketchybar main ●✚⇡ +12 -3 ⬢ Nx ⚡ Turbo v22 $2.34 10:42
╰─ 2.3s ✗1 ❯
Tech stack modules
| Module | Triggered by |
|---|---|
| Node · Bun · Deno | package.json · bun.lock · deno.json |
| Python | pyproject.toml · requirements.txt · Pipfile |
| Rust · OCaml · Swift | Cargo.toml · dune-project · Package.swift |
| Go · Perl · Elm · Crystal | go.mod · cpanfile · elm.json · shard.yml |
| Java · Ruby · Erlang · Scala | pom.xml · Gemfile · rebar.config · build.sbt |
| Kotlin · Haskell · Elixir · Julia · .NET · PHP · Gleam | native project files |
| C · C++ · Lua · Dart · V · R · Solidity · CMake · Buf | native project files |
| Zig · Nim | build.zig · nim.cfg |
Each module renders only inside a project of that language — your daily prompt stays clean.
Git indicators
| Icon | Meaning |
|---|---|
✓ | Clean working tree, up-to-date with remote |
● | Modified files in the working tree |
✚ | Staged for commit |
⇡ / ⇣ / ⇕ | Ahead / behind / diverged from remote |
… | Untracked files |
⊙ | Stashed changes exist |
» / ✖ | Renamed / deleted in index |
+12 -3 | Lines added / removed (git metrics) |
REBASE 3/10 | Operation in progress: rebase, merge, revert, cherry-pick, bisect, am |
Monorepo badges
| Badge | Tool | Triggered by |
|---|---|---|
⬢ Nx | Nx | nx.json · workspace.json |
⚡ Turbo | Turborepo | turbo.json |
pnpm-ws | pnpm workspaces | pnpm-workspace.yaml |
⚛ Lerna | Lerna | lerna.json |
⇶ Rush | Rush | rush.json |
☾ Moon | Moonrepo | .moon/ |
Bazel | Bazel | WORKSPACE · MODULE.bazel |
go.work | Go workspaces | go.work |
cargo-ws | Cargo workspace | Cargo.toml with [workspace] |
Badges stack — e.g. an Nx + pnpm repo lights up both. Cargo workspace uses a grep check, the rest are pure file/folder detection (zero cost outside monorepos).
Command status
| Indicator | Meaning |
|---|---|
✗ 1 | Exit code of last command (only on failure) |
2.3s | Command duration (only if > 2s) |
✦ 2 | Backgrounded jobs (Ctrl-Z’d processes) |
10:42 | Current time, right-aligned via right_format |
$2.34 | Project version from package.json / Cargo.toml / pyproject.toml etc. |
↕ 3 | Cached sudo creds / nested shells (SHLVL ≥ 3) |
⎈ ctx · ws · profile | Kubernetes context · Terraform workspace · AWS profile |
Claude Code statusline
Starship doubles as Claude Code’s statusline via the starship statusline claude-code profile. Renders the active model, a context-window gauge, session cost, and the git branch.
Rendered output (illustrative):
Opus 4.7 (1M) ████░░░░░░ 38% $2.34 main ✓
| Module | Behaviour |
|---|---|
claude_model | Short alias for the active model (Opus 4.7, Sonnet 4.6, Haiku 4.5) |
claude_context | 10-wide gauge — green < 50% · yellow 50–75% · orange 75–90% · red 90%+ |
claude_cost | Session USD — muted < $1 · yellow $1+ · orange $5+ · red $20+ |
# Auto-configured by install.sh — answer "yes" to the Starship statusline prompt.
# Or merge manually with jq (preserves existing keys):
jq '.statusLine = {type: "command", command: "starship statusline claude-code"}' \
~/.claude/settings.json | sponge ~/.claude/settings.json brew install starship
ln -sf ~/dotfiles/starship/starship.toml ~/.config/starship.toml Shell tools
lsd · Starship · Fastfetch · CodexBar.
# lsd — modern ls replacement
brew install lsd
alias ls='lsd'
alias ll='lsd -la'
alias lt='lsd --tree'
# fastfetch — system info (run on demand, not auto-loaded)
brew install fastfetch
fastfetch
CodexBar — AI token usage tracker. Install from github.com/steipete/CodexBar, then log in to Claude and Gemini via the menu bar app. Query usage with codexbar usage --provider claude --format json.
Zsh
Default shell on macOS. Starship prompt, fzf, zoxide, eza, Atuin history, and a fish-like input experience via four zsh plugins.
ln -sf ~/dotfiles/zsh/.zshrc ~/.zshrc What’s included
| Feature | Details |
|---|---|
| Prompt | Starship — cross-shell, fast, Tokyo Night compatible |
| Fuzzy finder | fzf with custom Tokyo Night colour scheme |
| Smart cd | zoxide rebinds cd — frecency-based jumps |
| History | Atuin — SQLite-backed, fuzzy Ctrl+R (local-only, no sync) |
| ls replacement | eza with icons — see the Eza section below |
| cat replacement | bat — syntax-highlighted output |
| Runtime managers | nvm · rbenv · bun · fnm |
| Input plugins | autosuggestions · syntax-highlighting · history-substring-search · fzf-tab |
Eza
Every ls-family alias is driven from a single $EZA_BASE variable plus a Tokyo-Night palette. ls is bound to the long view (same body as ll); plain grid is reachable via lG.
Shared base flags ($EZA_BASE):
--icons=always # nerd-font glyphs
--group-directories-first # folders rise to the top
--classify=auto # /, *, @ markers on a TTY
--color=always # keep colour through pagers
--color-scale=all # gradient on size + age columns
--color-scale-mode=gradient # smooth gradient, not buckets
--hyperlink # OSC-8 clickable paths
| Alias | Adds to $EZA_BASE | Purpose |
|---|---|---|
ls / ll | --long --header --git --time-style=relative | long view, git column, “3h ago” times |
l | --oneline | one file per line |
lG | — | plain grid view |
la / lla | --long ... --all | long view + hidden files |
lt / lt3 | --tree --level=2|3 | tree, depth-capped |
lta | --tree --all --git-ignore | tree honouring .gitignore |
ltd | --tree --only-dirs | directories-only tree |
lr | --sort=modified --reverse | newest first |
lS | --sort=size --reverse | largest first |
lg | --git --git-repos | long view with repo state per dir |
ld | --only-dirs | directories only |
Tokyo-Night palette ($EZA_COLORS) — eza uses LS_COLORS syntax. About 80 rules cover file-type metadata, permissions, git status, and per-extension hues. Reorder freely — first match wins.
| Category | Hue | Examples |
|---|---|---|
| Directories | Bold blue | all dirs |
| Executables / shell scripts | Green | .sh · .zsh · .fish · .vue |
| Source code (typed) | Cyan | .ts · .py · .go · .c · .css · Dockerfile |
| JavaScript / audio | Yellow | .js · .mp3 · .wav |
| Configs / HTML / Rust | Orange | .json · .toml · .yaml · .html · .rs · Makefile |
| Markup / images / video | Purple | .md · .png · .svg · .mp4 |
| Archives / .env / PDFs | Bold red | .zip · .tar.gz · .env · .pdf |
| Noise (dimmed) | Grey | .lock · .log · .bak · .DS_Store |
| Special | Bold + underline | README.md (pops in every repo) |
Plugins
Four plugins make zsh feel like fish. Loading order matters — fzf-tab first (touches compdef), syntax-highlighting second-to-last, history-substring-search dead last.
| Plugin | What it does | Keybinding |
|---|---|---|
fzf-tab | Replaces Tab with an fzf picker. | Tab |
zsh-autosuggestions | Fades in a suggested completion in Tokyo-Night grey (#565f89) as you type. | → / Ctrl+F to accept |
zsh-syntax-highlighting | Colours valid commands green, invalid red, strings yellow — as you type. | — |
zsh-history-substring-search | Type the start of an old command, then walk through matching history entries. | Ctrl+↑ / Ctrl+↓ |
The brew packages are in the Brewfile. fzf-tab has no brew formula — install.sh clones it idempotently to ~/.local/share/zsh/fzf-tab.
brew install zsh-autosuggestions zsh-syntax-highlighting zsh-history-substring-search
git clone --depth=1 https://github.com/Aloxaf/fzf-tab ~/.local/share/zsh/fzf-tab
Aliases
| Alias | Command |
|---|---|
| Listings (see the Eza section for the full set) | |
ls / ll | long view with git column + relative times |
cat | bat |
| Git | |
gs | git status |
g | git |
gc | git clone |
ga | git add * |
gm "msg" | git commit -m + git push (function) |
branch | git branch -r |
| Navigation | |
cd | zoxide — fuzzy jump by frecency |
dev [subpath] | cd into ~/Code or a subdirectory (tab-completes) |
| System | |
cc | claude —dangerously-skip-permissions (Claude Code) |
killport <port> | free a TCP port (SIGTERM then SIGKILL fallback) |
dock / undock | aerospace-sync (profile switch) |
scrcpy120 | scrcpy —video-codec=h265 —max-size=1920 —max-fps |
Per-project shortcuts (lumo, envpilot.dev, …) live in ~/.config/dotfiles/aliases.local.{sh,fish} — sourced by both shellrcs if present, never committed.
brew install fzf zoxide eza bat starship atuin \
zsh-autosuggestions zsh-syntax-highlighting zsh-history-substring-search
git clone --depth=1 https://github.com/Aloxaf/fzf-tab ~/.local/share/zsh/fzf-tab Fish
Friendly interactive shell. Aliases, eza palette, git function, and project shortcuts mirror zsh one-to-one. Autosuggestions / syntax-highlighting / history-substring-search are built-in to fish — no plugins needed.
brew install fish
mkdir -p ~/.config/fish
ln -sf ~/dotfiles/fish/config.fish ~/.config/fish/config.fish
# Set as default shell (optional)
echo $(which fish) | sudo tee -a /etc/shells
chsh -s $(which fish) What’s included
| Feature | Details |
|---|---|
| Prompt | Starship — starship init fish | source |
| Smart cd | zoxide rebinds cd — frecency-based jumps |
| History | Atuin — same Ctrl+R TUI as zsh, local-only |
| ls replacement | eza — same $EZA_BASE + Tokyo Night palette as zsh |
| cat replacement | bat — cat alias |
| Runtime managers | rbenv · fnm · bun |
| Built-in UX | autosuggestions · syntax-highlight · history search — no plugins required |
Aliases (one-to-one with zsh)
| Alias | Command |
|---|---|
ls / ll | eza long view (git + relative time) |
cat | bat |
cd | zoxide (frecency jump) |
dev [subpath] | cd into ~/Code/<arg> (tab-completes) |
gm "msg" | git commit -m + push (function) |
killport <port> | free a TCP port |
dock / undock | aerospace-sync |
gs | git status |
g | git |
gc | git clone |
ga | git add * |
Where to go next
- Desktop & WM — SketchyBar, AeroSpace, OmniWM.
- Apps & tools — the rest of the CLI + GUI inventory.
- Symlinks — how each config above lands in
~/.config/.