Skip to content

Instantly share code, notes, and snippets.

@batbrain9392
Last active June 15, 2026 10:25
Show Gist options
  • Select an option

  • Save batbrain9392/2ddea6dc775a4ab5fa16c492d26dc92f to your computer and use it in GitHub Desktop.

Select an option

Save batbrain9392/2ddea6dc775a4ab5fa16c492d26dc92f to your computer and use it in GitHub Desktop.
My zsh configuration
# --- Core Library ---
ohmyzsh/ohmyzsh path:lib
# --- OMZ Plugins ---
ohmyzsh/ohmyzsh path:plugins/git
# --- Interface ---
# The dropdown menu replacement
Aloxaf/fzf-tab
# Ghost text
zsh-users/zsh-autosuggestions
# Tab completions data
zsh-users/zsh-completions
# --- Highlighting ---
# MUST be last to correctly highlight everything above
zdharma-continuum/fast-syntax-highlighting
# ============================================================================
# Prerequisites
# ============================================================================
#
# Backup location: https://gist.github.com/batbrain9392/2ddea6dc775a4ab5fa16c492d26dc92f
# To update gist: run `zshconfigbackup` (function defined below)
#
# Required installations:
# - Homebrew: https://brew.sh
# - Antidote: brew install antidote
# - Starship: brew install starship
# - zoxide: brew install zoxide
# - fzf: brew install fzf
# - fnm: brew install fnm
# - eza: brew install eza (for fzf-tab directory previews)
# - bat: brew install bat (for fzf file previews)
# - tree: brew install tree (for fzf directory previews)
# - gh: brew install gh (for updating the gist backup)
# - FiraCode Nerd Font: brew install --cask font-fira-code-nerd-font (set as terminal font for icons)
#
# Required files (backed up in gist above):
# - ~/.zsh_plugins.txt: Plugin list for Antidote
#
# Optional:
# - tmux: brew install tmux
# - ~/.tmux.conf: tmux config (`t` in Aliases below attaches/creates a session per directory)
# - ghostty: brew install --cask ghostty
# - ~/.config/ghostty/config: Ghostty terminal config (theme, font, shell integration)
# - ~/.config/starship.toml: Starship prompt config (https://starship.rs/config/)
# - ~/.zshrc_secrets: Secrets/environment variables (not in gist)
#
# New machine setup:
# 1. Install Homebrew: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 2. Install tools: brew install antidote starship zoxide fzf fnm eza bat tree gh && brew install --cask font-fira-code-nerd-font
# 3. Download all files from the gist above into ~/
# If you use Ghostty: save `ghostty-config` from the gist as ~/.config/ghostty/config (mkdir -p ~/.config/ghostty)
# 4. Review and adjust machine/user-specific sections:
# - BREW_PREFIX: /opt/homebrew (Apple Silicon) vs /usr/local (Intel)
# - Zscaler block: remove if not behind a Zscaler proxy
# - PATH entries: adjust for your tools (pyenv, postgresql, etc.)
# - Aliases: remove or replace work-specific ones
# - 1Password / OP_VAULT: update or remove
# - zshconfigbackup: update gist ID to your own
# 5. Generate the plugin bundle: source $(brew --prefix)/opt/antidote/share/antidote/antidote.zsh && antidote bundle < ~/.zsh_plugins.txt > ~/.zsh_plugins.zsh
# 6. Restart shell: exec zsh
# 7. (Optional) Apply a Starship preset: starship preset <name> -o ~/.config/starship.toml
# e.g. starship preset nerd-font-symbols -o ~/.config/starship.toml (list presets: starship preset --list)
# 8. (Optional) Install Ghostty: brew install --cask ghostty
# Put your config at ~/.config/ghostty/config (see Prerequisites above; `zshconfigbackup` uploads it when present)
# 9. (Optional) tmux: brew install tmux — keep ~/.tmux.conf in sync via gist (see step 3)
# ============================================================================
# Startup Timing - Start (must be at top for accurate measurement)
# ============================================================================
# Start timing (only if not already set)
if [[ -z "$ZSH_START_TIME" ]]; then
typeset -F SECONDS
ZSH_START_TIME=$SECONDS
fi
# ============================================================================
# PATH Configuration
# ============================================================================
# Auto-deduplicate PATH entries
typeset -U path
path=(
"$HOME/.local/bin"
"$HOME/.pyenv/shims"
"/usr/local/opt/postgresql@15/bin"
"/Applications/Ghostty.app/Contents/MacOS"
$path
)
# ============================================================================
# Zscaler CA Certificate (required for Node.js tools behind Zscaler proxy)
# ============================================================================
# https://workday-dev.slack.com/archives/C09QK6W2PDG/p1764963868867399
ZSCALER_CA_DIR="${HOME}/.config/zscaler_config"
ZSCALER_CA_FILE="${ZSCALER_CA_DIR}/zscaler_root_ca.pem"
_zscaler_needs_refresh=1
if [[ -f "$ZSCALER_CA_FILE" ]]; then
_file_age=$(( $(date +%s) - $(stat -f %m "$ZSCALER_CA_FILE") ))
(( _file_age < 86400 )) && _zscaler_needs_refresh=0
fi
if (( _zscaler_needs_refresh )); then
if [[ ! -d "$ZSCALER_CA_DIR" ]]; then
mkdir -p "$ZSCALER_CA_DIR" 2>/dev/null && chmod 700 "$ZSCALER_CA_DIR"
fi
_current_cert="$(security find-certificate -c "Zscaler Root CA" -p /Library/Keychains/System.keychain 2>/dev/null)"
if [[ -n "$_current_cert" ]]; then
printf '%s\n' "$_current_cert" > "$ZSCALER_CA_FILE" 2>/dev/null && chmod 600 "$ZSCALER_CA_FILE"
fi
unset _current_cert
fi
unset _zscaler_needs_refresh _file_age
if [[ -f "$ZSCALER_CA_FILE" ]]; then
export NODE_EXTRA_CA_CERTS="$ZSCALER_CA_FILE"
fi
# ============================================================================
# Secrets & Environment Variables
# ============================================================================
[[ -f ~/.zshrc_secrets ]] && source ~/.zshrc_secrets
# Auto-sign in to 1Password CLI (seamless with desktop app unlocked)
# eval $(op signin --account peakon.1password.com 2>/dev/null) || true
export OP_VAULT="Employee"
# Hardcoded to avoid ~30ms subshell on every startup (brew --prefix never changes)
BREW_PREFIX="/opt/homebrew"
# ============================================================================
# Zsh Options & History
# ============================================================================
# History configuration
HISTFILE="$HOME/.zsh_history"
HISTSIZE=100000
SAVEHIST=100000
setopt SHARE_HISTORY # Share history between all sessions
setopt HIST_IGNORE_ALL_DUPS # Don't record duplicate entries (even non-consecutive)
setopt HIST_IGNORE_SPACE # Don't record entries starting with space
setopt HIST_REDUCE_BLANKS # Remove superfluous blanks
# Other useful options
setopt AUTO_CD # cd by typing directory name if it's not a command
setopt COMPLETE_IN_WORD # Complete from both ends of a word
setopt ALWAYS_TO_END # Move cursor to end of word after completion
# ============================================================================
# Antidote - Fast Zsh Plugin Manager
# ============================================================================
# Initialize completions before plugins load (needed for compdef used by OMZ plugins)
autoload -Uz compinit && compinit -C
# Static plugin file — regenerate via `zshrebundle` after editing .zsh_plugins.txt
source ~/.zsh_plugins.zsh
# ============================================================================
# Zoxide - Smart Directory Navigation
# ============================================================================
# Cache zoxide init output — regenerates when binary is updated (e.g. brew upgrade)
_zoxide_cache="${XDG_CACHE_HOME:-$HOME/.cache}/zoxide-init.zsh"
if [[ ! -f "$_zoxide_cache" || "${commands[zoxide]}" -nt "$_zoxide_cache" ]]; then
command zoxide init zsh > "$_zoxide_cache"
fi
source "$_zoxide_cache"
# ============================================================================
# Starship Prompt
# ============================================================================
# Cache starship init output — regenerates when binary is updated (e.g. brew upgrade)
_starship_cache="${XDG_CACHE_HOME:-$HOME/.cache}/starship-init.zsh"
if [[ ! -f "$_starship_cache" || "${commands[starship]}" -nt "$_starship_cache" ]]; then
command starship init zsh > "$_starship_cache"
fi
source "$_starship_cache"
# ============================================================================
# fzf - Fuzzy Finder
# ============================================================================
source <(fzf --zsh)
export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border'
export FZF_CTRL_T_OPTS="--preview 'bat --color=always --style=header,grid --line-range :300 {} 2>/dev/null || cat {}'"
export FZF_CTRL_R_OPTS="--preview 'echo {}' --preview-window down:3:hidden:wrap --bind '?:toggle-preview'"
export FZF_ALT_C_OPTS="--preview 'tree -C {} | head -200'"
# ============================================================================
# fzf-tab Configuration
# ============================================================================
zstyle ':completion:*:git-checkout:*' sort false # Disable sort when completing `git checkout`
zstyle ':completion:*:descriptions' format '[%d]' # Set descriptions format to enable group support
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath' # Preview directory's content with eza
zstyle ':fzf-tab:*' switch-group '<' '>' # Switch group using `<` and `>`
# ============================================================================
# Command Not Found Handler
# ============================================================================
# The old homebrew-command-not-found tap is archived — now built into brew
source "${BREW_PREFIX}/Library/Homebrew/command-not-found/handler.sh"
# ============================================================================
# Node Version Management (fnm)
# ============================================================================
# Cache fnm env output — regenerates when binary is updated (e.g. brew upgrade)
_fnm_cache="${XDG_CACHE_HOME:-$HOME/.cache}/fnm-env.zsh"
if [[ ! -f "$_fnm_cache" || "${commands[fnm]}" -nt "$_fnm_cache" ]]; then
command fnm env --use-on-cd --shell zsh > "$_fnm_cache"
fi
source "$_fnm_cache"
# ============================================================================
# Aliases
# ============================================================================
zshconfigbackup() {
local gist_id='2ddea6dc775a4ab5fa16c492d26dc92f'
local gist_url="https://gist.github.com/batbrain9392/${gist_id}"
local fields=(
--field "files[.zshrc][content]=@$HOME/.zshrc"
--field "files[.zsh_plugins.txt][content]=@$HOME/.zsh_plugins.txt"
)
[[ -f "$HOME/.config/ghostty/config" ]] && fields+=(--field "files[ghostty-config][content]=@$HOME/.config/ghostty/config")
[[ -f "$HOME/.tmux.conf" ]] && fields+=(--field "files[tmux.conf][content]=@$HOME/.tmux.conf")
gh api --method PATCH "/gists/$gist_id" "${fields[@]}" --silent && echo "Gist updated - ${gist_url}"
}
alias ddwn="docker compose down -v"
alias ddup="docker compose pull && docker compose up -d --wait"
alias ddcln="docker system prune -af --volumes"
alias updtrepo="gfa && gl && npm i"
alias apistart="updtrepo && ddwn && ddup && ddcln && npm run reset && npm start"
alias artifactorysetup="pkn artifactory setup && docker login docker-dev-artifactory.workday.com"
alias brewupgrade="brew update && brew upgrade && brew cleanup"
alias zshrebundle="source ${BREW_PREFIX}/opt/antidote/share/antidote/antidote.zsh && antidote bundle < ~/.zsh_plugins.txt > ~/.zsh_plugins.zsh"
alias zshreload="brewupgrade && zshrebundle && exec zsh"
# ============================================================================
# Startup Timing - End (must be at bottom to measure full startup time)
# ============================================================================
# Display startup time (only on initial load, and only if ZSH_STARTUP_TIME env var is set)
# To see startup time: ZSH_STARTUP_TIME=1 exec zsh
if [[ -n "$ZSH_START_TIME" && -n "$ZSH_STARTUP_TIME" ]]; then
startup_time=$(($SECONDS - $ZSH_START_TIME))
if (( startup_time > 0.1 )); then # Only show if > 100ms
echo "⏱️ zsh startup: ${startup_time}s"
fi
unset ZSH_START_TIME ZSH_STARTUP_TIME
fi
# --- Font (FiraCode Nerd Font with ligatures) ---
font-family = "FiraCode Nerd Font"
font-size = 12
font-feature = calt
font-feature = liga
font-thicken = true
bold-is-bright = true
# --- Theme (auto light/dark synced with macOS) ---
theme = Github Dark
# --- Window ---
window-padding-x = 6
window-padding-y = 6
window-save-state = always
# --- macOS ---
quit-after-last-window-closed = true
confirm-close-surface = false
copy-on-select = clipboard
macos-option-as-alt = left
mouse-scroll-multiplier = 2
# --- Keybinds (macOS-style word/line nav & selection) ---
keybind = alt+left=text:\x1bb
keybind = alt+right=text:\x1bf
keybind = super+left=text:\x01
keybind = super+right=text:\x05
# --- Core ---
set -g mouse on
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
set -g history-limit 10000
set -g set-clipboard on
set -sg escape-time 10
set -g focus-events on
# --- Prefix: Ctrl+a ---
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# --- Splits (current path) ---
bind \\ split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# --- Pane Labels ---
set -g pane-border-status top
set -g pane-border-format " #P:#{pane_title} "
# --- Catppuccin Theme (loaded via TPM) ---
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'catppuccin/tmux#v2.1.3'
set -g @catppuccin_flavor 'mocha'
set -g @catppuccin_window_status_style "rounded"
set -g @catppuccin_date_time_text " %H:%M"
run '~/.tmux/plugins/tpm/tpm'
# --- Status Bar (must be after TPM loads Catppuccin modules) ---
set -g status-right-length 100
set -g status-left-length 100
set -g status-left ""
set -g status-right "#{E:@catppuccin_status_application}"
set -ag status-right "#{E:@catppuccin_status_session}"
set -ag status-right "#{E:@catppuccin_status_date_time}"

ghost commented Jan 23, 2026

Copy link
Copy Markdown

Hey there,
first of all: I really like your extensive configuration, which is also very well documented! One thing I noticed, however, is that homebrew-command-not-found seems to have been merged into brew, making lines 155-160 obsolete!

@batbrain9392

batbrain9392 commented Mar 27, 2026

Copy link
Copy Markdown
Author

Thanks for the heads-up! You're right — the tap is archived now. Updated to source the built-in handler at ${BREW_PREFIX}/Library/Homebrew/command-not-found/handler.sh instead. Kept it because it suggests brew install <formula> when a command isn't found — useful enough to justify the negligible startup cost.

@batbrain9392

Copy link
Copy Markdown
Author

I've also optimised the setup a bit more, cutting the load time by 30-50%.

ghost commented Mar 27, 2026

Copy link
Copy Markdown

I've also optimised the setup a bit more, cutting the load time by 30-50%.

Sounds impressive 🤔

@batbrain9392

Copy link
Copy Markdown
Author

Credit to claude 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment