# Interactive shell only. PATH lives in ~/.zshenv (agents do not load this file). # Personal overlays: ~/.config/zshrc/*.zsh (before oh-my-zsh). # Machine-local env: ~/.config/zsh/local.zsh (from ~/.zshenv). # Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc. # if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then # source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" # fi export TERM="xterm-256color" # Skip oh-my-zsh's completion security audit (compaudit). export ZSH_DISABLE_COMPFIX=true export ZSH=$HOME/.oh-my-zsh # Agent/AI terminals (Cursor sets CURSOR_AGENT) get a light theme; humans use p10k. if [[ -n "$CURSOR_AGENT" ]]; then ZSH_THEME="robbyrussell" else ZSH_THEME="powerlevel10k/powerlevel10k" fi zstyle ':omz:update' frequency 30 plugins=( zsh-autosuggestions zsh-syntax-highlighting history-substring-search systemd k extract sudo fzf-tab poetry ) # In ~/.config/zshrc/*.zsh: # plugins+=(docker) # plugins=(${plugins:#zsh-autosuggestions}) fpath+=$ZSH/custom/plugins/zsh-completions/src if [[ "$OSTYPE" == "darwin"* ]] && command -v brew &> /dev/null; then FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}" fi mkdir -p ~/.cache/zsh autoload -U compinit && compinit -C -d ~/.cache/zsh/.zcompdump SAVEHIST=50000 cheat() { if [ "$2" ]; then curl "https://cheat.sh/$1/$2+$3+$4+$5+$6+$7+$8+$9+$10" else curl "https://cheat.sh/$1" fi } speedtest() { setopt localoptions pipefail curl -fsSL https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python3 - } dadjoke() { curl https://icanhazdadjoke.com } cleanzip() { zip -d "$@" __MACOSX/\* \*/.DS_Store } ipgeo() { if [ "$1" ]; then curl "https://api.db-ip.com/v2/free/$1" else curl "https://api.db-ip.com/v2/free/$(myip)" fi } # Personal / tool overlays before oh-my-zsh so plugins+=(…) apply. ZSH_CONFIGS_DIR="$HOME/.config/zshrc" for file in "$ZSH_CONFIGS_DIR"/*(DN); do if [ -f "$file" ]; then source "$file" fi done source "$ZSH/oh-my-zsh.sh" # Aliases after omz so they win over omz defaults. alias myip="wget -qO- https://wtfismyip.com/text" alias l="eza --hyperlink -lA --sort=modified --reverse --classify" alias e="exit" alias ip="ip --color=auto" alias a='eza -la --git --colour-scale all -g --smart-group --icons always --hyperlink' alias aa='eza -la --git --colour-scale all -g --smart-group --icons always -s modified -r --hyperlink' # rm → Trash. Shell snapshots restore functions but not global arrays, so re-resolve when empty. _resolve_trash_cmd() { if [[ "$OSTYPE" == darwin* && -x /usr/bin/trash ]]; then typeset -ga _TRASH_CMD=(/usr/bin/trash) elif [[ "$OSTYPE" == darwin* ]] && command -v rmtrash &> /dev/null; then typeset -ga _TRASH_CMD=(rmtrash) elif [[ "$OSTYPE" != darwin* ]] && command -v gio &> /dev/null; then typeset -ga _TRASH_CMD=(gio trash) elif [[ "$OSTYPE" != darwin* ]] && command -v trash-put &> /dev/null; then typeset -ga _TRASH_CMD=(trash-put) fi } _resolve_trash_cmd if (( ${#_TRASH_CMD[@]} )); then rm() { (( ${#_TRASH_CMD[@]} )) || _resolve_trash_cmd (( ${#_TRASH_CMD[@]} )) || { command rm "$@"; return } local force=0 arg local -a paths existing for arg in "$@"; do case "$arg" in --) ;; -*f*) force=1 ;; -*) ;; *) paths+=("$arg") ;; esac done (( ${#paths[@]} )) || return 0 if (( force )); then for arg in "${paths[@]}"; do [[ -e "$arg" || -L "$arg" ]] && existing+=("$arg") done (( ${#existing[@]} )) || return 0 "${_TRASH_CMD[@]}" "${existing[@]}" else "${_TRASH_CMD[@]}" "${paths[@]}" fi } fi if [[ -x "$HOME/.fzf/bin/fzf" ]] && ! fzf --zsh >/dev/null 2>&1; then path=("$HOME/.fzf/bin" ${path:#$HOME/.fzf/bin}) fi [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh export FZF_DEFAULT_OPS="--extended" command -v zoxide &> /dev/null && eval "$(zoxide init zsh)" alias j="z" if (( $+functions[k] )); then alias k="k -h" fi