Skip to content

Instantly share code, notes, and snippets.

@djheru
Last active May 3, 2026 05:52
Show Gist options
  • Select an option

  • Save djheru/1e11675c6de87aba0e7ab90a2391a02e to your computer and use it in GitHub Desktop.

Select an option

Save djheru/1e11675c6de87aba0e7ab90a2391a02e to your computer and use it in GitHub Desktop.
zshrc
# ============================================================================
# ~/.zshrc — Philip
# Layout:
# 1. PATH
# 2. Oh My Zsh + plugins
# 3. History + shell options
# 4. Editor / pager
# 5. Modern CLI replacements (eza, bat, fzf, zoxide, ...)
# 6. Aliases & helper functions
# 7. AWS multi-account helpers
# 8. Lazy-loaded toolchains (nvm, conda, pyenv)
# 9. Env vars (non-secret)
# 10. Secrets (sourced from ~/.config/zsh/secrets.zsh)
# 11. Local overrides (~/.zshrc.local)
# ============================================================================
# Uncomment to profile startup: zmodload zsh/zprof then run `zprof`
# zmodload zsh/zprof
# ---------- 1. PATH ---------------------------------------------------------
typeset -U path PATH # auto-dedupe PATH
path=(
/opt/homebrew/bin /opt/homebrew/sbin # Apple Silicon brew
/usr/local/opt/libpq/bin
$HOME/bin
$HOME/.local/bin
$HOME/.cache/lm-studio/bin
$path
)
export PATH
# ---------- 2. Oh My Zsh ----------------------------------------------------
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="agnoster" # try powerlevel10k or starship for speed
# ZSH_THEME="" # For use with starship
COMPLETION_WAITING_DOTS="true"
HYPHEN_INSENSITIVE="true"
DISABLE_UNTRACKED_FILES_DIRTY="true" # big speedup in large git repos
plugins=(
git
aws
docker
docker-compose
npm
node
brew
macos
history-substring-search
command-not-found
zsh-autosuggestions # 3rd-party — install instructions below
zsh-syntax-highlighting # 3rd-party — MUST be last in the list
)
source $ZSH/oh-my-zsh.sh
# ---------- 3. History ------------------------------------------------------
HISTFILE="$HOME/.zsh_history"
HISTSIZE=500000
SAVEHIST=500000
setopt BANG_HIST EXTENDED_HISTORY INC_APPEND_HISTORY SHARE_HISTORY
setopt HIST_EXPIRE_DUPS_FIRST HIST_IGNORE_DUPS HIST_IGNORE_ALL_DUPS
setopt HIST_FIND_NO_DUPS HIST_IGNORE_SPACE HIST_SAVE_NO_DUPS
setopt HIST_REDUCE_BLANKS HIST_VERIFY
# Quality-of-life shell behaviour
setopt AUTO_CD # `Workspace` instead of `cd Workspace`
setopt AUTO_PUSHD PUSHD_IGNORE_DUPS PUSHD_SILENT # cd builds a stack you can pop
setopt INTERACTIVE_COMMENTS # allow # comments in interactive shell
setopt EXTENDED_GLOB # **/foo, ^pattern, etc.
setopt NO_BEEP
# ---------- 4. Editor / pager ----------------------------------------------
if [[ -n $SSH_CONNECTION ]]; then
export EDITOR='vim'
else
export EDITOR='code -w' # swap for cursor / nvim / mvim
fi
export VISUAL=$EDITOR
export PAGER=less
export LESS='-R -F -X --mouse'
# ---------- 5. Modern CLI replacements (auto-detected if installed) --------
# brew install eza bat ripgrep fd fzf zoxide git-delta tldr btop
if command -v eza >/dev/null 2>&1; then
alias ls='eza --group-directories-first --icons'
alias ll='eza -lah --git --group-directories-first --icons'
alias lt='eza --tree --level=2 --icons'
alias ltt='eza --tree --level=3 --icons'
fi
command -v bat >/dev/null 2>&1 && alias cat='bat --paging=never'
command -v fd >/dev/null 2>&1 && alias find='fd'
command -v rg >/dev/null 2>&1 && alias grep='rg'
# fzf — fuzzy finder. Ctrl-R = history, Ctrl-T = files, Alt-C = cd
[[ -f ~/.fzf.zsh ]] && source ~/.fzf.zsh
export FZF_DEFAULT_OPTS='--height 60% --layout=reverse --border --info=inline'
if command -v fd >/dev/null 2>&1; then
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'
fi
# zoxide — `z foo` jumps to the most-frecent dir matching "foo"
command -v zoxide >/dev/null 2>&1 && eval "$(zoxide init zsh)"
# ---------- 6. General aliases & functions ---------------------------------
alias reload='source ~/.zshrc && echo "✔ zshrc reloaded"'
alias zshconfig='$EDITOR ~/.zshrc'
alias path='echo $PATH | tr ":" "\n"'
alias myip='curl -s https://api.ipify.org && echo'
alias localip='ipconfig getifaddr en0'
alias ports='lsof -P -iTCP -sTCP:LISTEN'
alias listenports='lsof -P -iTCP -sTCP:LISTEN' # keeping your old name too
alias serve='python3 -m http.server'
alias weather='curl -s "wttr.in/Mesa?format=v2"'
cheat() { curl -s "cheat.sh/$1"; } # `cheat tar`, `cheat ffmpeg/...`
# Make a dir and cd into it
mkcd() { mkdir -p "$1" && cd "$1"; }
# Universal extractor — `extract whatever.tar.gz`
extract() {
[[ -f $1 ]] || { echo "'$1' is not a file"; return 1; }
case $1 in
*.tar.bz2|*.tbz2) tar xjf "$1" ;;
*.tar.gz|*.tgz) tar xzf "$1" ;;
*.tar.xz) tar xJf "$1" ;;
*.tar) tar xf "$1" ;;
*.bz2) bunzip2 "$1" ;;
*.gz) gunzip "$1" ;;
*.zip) unzip "$1" ;;
*.rar) unrar x "$1" ;;
*.7z) 7z x "$1" ;;
*.Z) uncompress "$1" ;;
*) echo "Don't know how to extract '$1'"; return 1 ;;
esac
}
# Kill whatever is hogging a port — `killport 3000`
killport() { lsof -ti tcp:"$1" | xargs kill -9; }
# Auto-load a project's .env into the current shell
dotenv() { [[ -f .env ]] && set -a && source .env && set +a && echo "✔ loaded .env"; }
# Git
alias gs='git status -sb'
alias gco='git checkout'
alias gcb='git checkout -b'
alias gp='git pull --rebase'
alias gP='git push'
alias gl='git log --oneline --graph --decorate -20'
alias gitlog='git log --pretty=format:"%h%x09%an%x09%ad%x09%s"'
alias gundo='git reset HEAD~1 --soft'
alias gnuke='git reset --hard HEAD'
# Docker
alias dcup='docker compose up -d'
alias dcdn='docker compose down'
alias dcl='docker compose logs -f --tail 200'
alias dockerclean='docker system prune -a -f && docker volume prune -a -f'
# Terraform / CDK / Nest
alias tf='terraform'
alias cdk='npx aws-cdk'
alias cdk1='npx aws-cdk@1'
alias cdk2='npx aws-cdk@2'
alias nest='npx @nestjs/cli'
# Python venv — renamed from `pyenv` (which collided with the real pyenv binary!)
mkvenv() { python3 -m venv .venv && source .venv/bin/activate; }
alias venv='source .venv/bin/activate'
# ---------- 7. AWS multi-account helpers -----------------------------------
# Personal (non-SSO)
awsloginpersonal() {
export AWS_PROFILE=personal
export AWS_EB_PROFILE=personal
export CDK_ENV=dev
export AWS_ACCOUNT_ID=205375198116
export AWS_DEFAULT_ACCOUNT_ID=205375198116
}
# SSO core: relies on $AWSENV and $AWSACCT being set by a wrapper
awslogin() {
export AWS_PROFILE=$AWSENV
aws sso login --profile "$AWSENV" || return 1
export AWS_ACCOUNT_ID=$AWSACCT
export AWS_DEFAULT_ACCOUNT_ID=$AWSACCT
export CDK_DEFAULT_ACCOUNT=$AWSACCT
aws sts get-caller-identity
}
_awsenv() { export AWSENV=$1 CDK_ENV=$1 AWSACCT=$2; awslogin; }
awsdev() { _awsenv dev 190423078218; }
awsprod() { _awsenv prod 276541279630; }
awsstaging() { _awsenv staging 228708224037; }
awscicd() { _awsenv cicd 083171692404; }
awsbfdev() { _awsenv bfdev 816069134203; }
awsbfprod() { _awsenv bfprod 982081089955; }
# Quick "who am I right now?" — handy after juggling profiles
awswhoami() {
echo "AWS_PROFILE: ${AWS_PROFILE:-(unset)}"
echo "AWS_ACCOUNT_ID: ${AWS_ACCOUNT_ID:-(unset)}"
echo "CDK_ENV: ${CDK_ENV:-(unset)}"
echo "REGION: ${AWS_DEFAULT_REGION:-(unset)}"
aws sts get-caller-identity 2>/dev/null
}
# Push your SSH pubkey to an EC2 instance: `pushkey i-0123abcd...`
pushkey() {
local id="${1:-$INSTANCE_ID}"
[[ -z $id ]] && { echo "Usage: pushkey <instance-id> (or set \$INSTANCE_ID)"; return 1; }
aws ec2-instance-connect send-ssh-public-key \
--profile dev \
--instance-id "$id" \
--availability-zone us-east-1a \
--instance-os-user ec2-user \
--ssh-public-key file://~/.ssh/cdk_key.pub
}
# ---------- 8. Lazy-loaded toolchains --------------------------------------
# nvm: the eager init was costing you ~500ms per shell open. This stub
# replaces itself with the real thing the first time you call node/npm/npx/nvm.
# nvm: PATH is set eagerly (cheap), nvm command itself is lazy-loaded.
export NVM_DIR="$HOME/.nvm"
# Add the default node version's bin to PATH without sourcing nvm.sh.
if [[ -f "$NVM_DIR/alias/default" ]]; then
_nvm_default="$(<"$NVM_DIR/alias/default")"
if [[ -d "$NVM_DIR/versions/node/v${_nvm_default}/bin" ]]; then
path=("$NVM_DIR/versions/node/v${_nvm_default}/bin" $path)
elif [[ -d "$NVM_DIR/versions/node/${_nvm_default}/bin" ]]; then
path=("$NVM_DIR/versions/node/${_nvm_default}/bin" $path)
else
# Default alias points to something like 'lts/iron' — resolve by picking
# the highest installed version as a fallback.
_nvm_fallback="$(ls -d "$NVM_DIR"/versions/node/v* 2>/dev/null | sort -V | tail -1)"
[[ -n $_nvm_fallback ]] && path=("$_nvm_fallback/bin" $path)
unset _nvm_fallback
fi
unset _nvm_default
fi
# Lazy-load just the `nvm` command (used for `nvm install`, `nvm use`, etc.)
nvm() {
unset -f nvm
[[ -s "$NVM_DIR/nvm.sh" ]] && \. "$NVM_DIR/nvm.sh"
[[ -s "$NVM_DIR/bash_completion" ]] && \. "$NVM_DIR/bash_completion"
nvm "$@"
}
# Auto-switch node when entering a dir with .nvmrc
autoload -U add-zsh-hook
load-nvmrc() {
[[ -f .nvmrc ]] || return
# Force nvm to load if it hasn't already
[[ -z $NVM_BIN ]] && nvm --version >/dev/null 2>&1
local node_version="$(nvm version)"
local nvmrc_node_version="$(nvm version "$(cat .nvmrc)")"
if [[ $nvmrc_node_version == "N/A" ]]; then
nvm install
elif [[ $nvmrc_node_version != $node_version ]]; then
nvm use
fi
}
add-zsh-hook chpwd load-nvmrc
# Conda — also lazy-loaded (saves ~300ms)
conda() {
unset -f conda
__conda_setup="$('/Users/pdamra/anaconda3/bin/conda' 'shell.zsh' 'hook' 2>/dev/null)"
if [[ $? -eq 0 ]]; then
eval "$__conda_setup"
elif [[ -f "/Users/pdamra/anaconda3/etc/profile.d/conda.sh" ]]; then
. "/Users/pdamra/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/Users/pdamra/anaconda3/bin:$PATH"
fi
unset __conda_setup
conda "$@"
}
# pyenv (only init if installed; no longer shadowed by an alias)
command -v pyenv >/dev/null 2>&1 && eval "$(pyenv init -)"
# Local-bin env (rye / uv / poetry shim)
[[ -f "$HOME/.local/bin/env" ]] && . "$HOME/.local/bin/env"
# ---------- 9. Non-secret env vars -----------------------------------------
export WORKSPACE_ROOT="$HOME/Workspace"
export AWS_PROFILE=dev
export AWS_DEFAULT_REGION=us-east-1
export CDK_DEFAULT_REGION=us-east-1
export CDK_KEY="$HOME/.ssh/cdk_key"
export DEFAULT_USER=$USER
export AWS_SDK_LOAD_CONFIG=1
export JSII_SILENCE_WARNING_UNTESTED_NODE_VERSION=1
export CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000
export LANGCHAIN_TRACING_V2=true
# ---------- 10. Secrets ----------------------------------------------------
# All API keys/tokens live in ~/.config/zsh/secrets.zsh (chmod 600, gitignored).
[[ -f "$HOME/.config/zsh/secrets.zsh" ]] && source "$HOME/.config/zsh/secrets.zsh"
# Prosaist JWT helper — pulls creds from secrets.zsh
pjwt() {
curl --request POST \
--url https://auth0.prosaist.io/oauth/token \
--header 'content-type: application/json' \
--data "{\"client_id\":\"$PROSAIST_CLIENT_ID\",\"client_secret\":\"$PROSAIST_CLIENT_SECRET\",\"audience\":\"https://dev.prosaist.io/\",\"grant_type\":\"client_credentials\"}"
}
# ---------- 11. Local overrides --------------------------------------------
# Anything you don't want tracked in dotfiles goes here.
[[ -f "$HOME/.zshrc.local" ]] && source "$HOME/.zshrc.local"
# ---------- 12. Starship --------------------------------------------
# Starship from brew for the prompt
# eval "$(starship init zsh)"
# ============================================================================
# ~/.config/zsh/secrets.zsh
#
# Setup:
# mkdir -p ~/.config/zsh
# cp this-file ~/.config/zsh/secrets.zsh
# chmod 600 ~/.config/zsh/secrets.zsh
# echo '.config/zsh/secrets.zsh' >> ~/.gitignore_global # belt-and-braces
#
# ============================================================================
# ---- GitHub ----
export GH_NPM_TOKEN=""
export GH_TOKEN=""
# ---- LLM / search APIs ----
export ANTHROPIC_API_KEY=""
export OPENAI_API_KEY=""
export TAVILY_API_KEY=""
export SERPAPI_API_KEY=""
export LANGCHAIN_API_KEY=""
# ---- Trading / market data ----
export OANDA_API_KEY=""
export OANDA_ACCOUNT_NUMBER=""
export ALPACA_PAPER_API_KEY=""
export ALPACA_PAPER_API_SECRET=""
export ALPACA_LIVE_API_KEY=""
export ALPACA_LIVE_API_SECRET=""
export EXCHANGE_KEY="" # Kraken
export EXCHANGE_SECRET=""
# ---- Freqtrade / Telegram bot ----
export TELEGRAM_TOKEN=""
export TELEGRAM_CHAT_ID=""
# ---- Prosaist ----
export PROSAIST_CLIENT_ID=""
export PROSAIST_CLIENT_SECRET=""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment