Files
skel/dotfiles/zshrc
David Tomaschik db2c02bd2d Cleanup
2026-04-21 15:59:38 -07:00

324 lines
9.2 KiB
Bash
Executable File

# For interactive shells
[[ -n "$ZSH_PROFILE" ]] && {
zmodload zsh/datetime
zshrc_start_time=$EPOCHREALTIME
zmodload zsh/zprof
}
HISTFILE=~/.zhistory
HISTSIZE=10000
SAVEHIST=10000
setopt \
ALWAYS_TO_END \
APPEND_HISTORY \
AUTO_CD \
AUTO_LIST \
AUTO_MENU \
AUTO_PARAM_SLASH \
AUTO_PUSHD \
BANG_HIST \
C_BASES \
COMPLETE_IN_WORD \
EXTENDED_GLOB \
EXTENDED_HISTORY \
HIST_EXPIRE_DUPS_FIRST \
HIST_FIND_NO_DUPS \
HIST_IGNORE_DUPS \
HIST_IGNORE_SPACE \
HIST_LEX_WORDS \
HIST_SAVE_NO_DUPS \
HIST_VERIFY \
INTERACTIVE_COMMENTS \
LONG_LIST_JOBS \
MULTIOS \
NO_CLOBBER \
NO_HUP \
NOMATCH \
NOTIFY \
PUSHD_IGNORE_DUPS \
PUSHD_SILENT \
PUSHD_TO_HOME \
RC_QUOTES \
SHARE_HISTORY
unsetopt \
BEEP \
CDABLE_VARS \
HIST_BEEP \
LIST_BEEP \
FLOW_CONTROL \
MAIL_WARNING \
HUP \
BG_NICE \
CHECK_JOBS
# vi keybindings
bindkey -v
# Allow core files
ulimit -c unlimited
DIRSTACKSIZE=16
export OS="$(uname 2>/dev/null || echo "Unknown")"
# Set terminal title
case $TERM in
# Only set the title for terminals that are likely to support it
xterm*|screen*)
# add-zsh-hook is a zsh utility for managing hooks
autoload -U add-zsh-hook
# Variable to hold the manual title, initialized to empty
MANUAL_TERMINAL_TITLE=""
# Manually set the terminal title. Clears the title if no argument is given.
set_title() {
MANUAL_TERMINAL_TITLE="${1:-}" # Assign argument or empty string
# If the argument is empty, restore the automatic title.
if [ -z "${MANUAL_TERMINAL_TITLE}" ] ; then
_term_precmd
return
fi
# Otherwise, set the manual title.
if test -n "${TMUX}" ; then
print -Pn "\e]2;${MANUAL_TERMINAL_TITLE}\e\\"
else
print -Pn "\e]0;${MANUAL_TERMINAL_TITLE}\a"
fi
}
# precmd hook runs before each prompt
_term_precmd() {
# If a manual title is set, do nothing.
if test -n "${MANUAL_TERMINAL_TITLE}" ; then
return
fi
# emulate zsh to ensure consistent behavior
emulate -L zsh
# If we are in tmux, we want to set the window title
if test -n "${TMUX}" ; then
# Set tmux window title to a truncated path
print -Pn "\e]2;%16<..<%~\e\\"
else
# this will also work in tmux but is not what we want
# Set terminal title to user@host: path
print -Pn "\e]0;%n@%m: %~\a"
fi
}
# preexec hook runs before each command
_term_preexec() {
# If a manual title is set, do nothing.
if test -n "${MANUAL_TERMINAL_TITLE}" ; then
return
fi
# emulate zsh to ensure consistent behavior
emulate -L zsh
# Set local options to avoid affecting the rest of the shell
setopt LOCAL_OPTIONS
setopt EXTENDED_GLOB
# extract the first word of the command that is not a match for the
# pattern
# (w) = match word
# (r) = subscript value, not index
# This extracts the command, ignoring environment variables and common wrappers
local cmd=${1[(wr)^(*=*|sudo|ssh|mosh|-*)]:gs/%/%%}
# If we are in tmux, we want to set the window title
if test -n "${TMUX}" ; then
# Set the tmux window title to the command being run
print -Pn "\e]2;${cmd}\e\\"
else
# this will also work in tmux but is not what we want
# Set the terminal title to include the command being run
print -Pn "\e]0;%n@%m: %~ ($cmd)\a"
fi
}
# Add the hooks to zsh
add-zsh-hook precmd _term_precmd
add-zsh-hook preexec _term_preexec
;;
esac
autoload -U colors && colors
PS1="%{$fg[black]%}[%{$fg[yellow]%}%h%{$fg[black]%}] %{%(!.$fg[red].$fg[green])%}%8>..>%n%>>%{$fg[white]%}@%{$fg[blue]%}%12>..>%m%>>%{$fg[white]%}:%{$fg[green]%}%32<...<%~%<<%{$fg[white]%}%#%{$reset_color%} "
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
zstyle ':completion::complete:*' use-cache on
zstyle ':completion::complete:*' cache-path "${ZDOTDIR:-$HOME}/.zcompcache"
# .profile is universal
emulate sh -c '. /etc/profile'
emulate sh -c '. ~/.profile'
# Additional Keybindings
bindkey '^[[A' history-search-backward
bindkey '^[[B' history-search-forward
# ctrl-arrow keys
bindkey '^[[1;5C' forward-word
bindkey '^[[1;5D' backward-word
bindkey '^P' up-history
bindkey '^N' down-history
bindkey '^?' backward-delete-char
bindkey '^h' backward-delete-char
# ok, a few emacs convenience bindings
bindkey '^w' backward-kill-word
bindkey '^r' history-incremental-search-backward
# delete really deletes
bindkey "^[[3~" delete-char
source_if_existing() {
[[ -f "${1}" ]] && source "${1}"
}
source_first_existing() {
while (($#)); do
if test -e "${1}" ; then
source "${1}"
return
fi
shift
done
return 1
}
have_command() {
command -v "${1}" &>/dev/null
}
if test -d ${HOME}/.local/bin ; then
export PATH="${HOME}/.local/bin:${PATH}"
fi
# Source extras and aliases if interactive
if [[ $- == *i* ]] ; then
source_if_existing $HOME/.aliases
source_if_existing $HOME/.aliases.local
# zsh-only-ism to avoid error if glob doesn't expand
# specifically sets NULLGLOB for this one glob
typeset -gA _deferred_comps
compdef() {
# Store the arguments: first arg is the function, the rest are the commands
local func=$1
shift
for cmd in "$@"; do
_deferred_comps[$cmd]=$func
done
}
for file in $HOME/.zshrc.d/[a-zA-Z0-9]*.zsh(N) ; do
source "$file"
done
# extra completions, prompt
fpath=(~/.zshrc.completions ~/.zshrc.d/matir_prompt $fpath)
# Homebrew on mac
if test -x /opt/homebrew/bin/brew ; then
eval $(/opt/homebrew/bin/brew shellenv)
fi
# Completion
zstyle ':compinstall' filename "${HOME}/.zshrc"
zstyle ':completion:*' users root ${USER}
# Modules after fpath
autoload -Uz compinit
for cmd func in "${(@kv)_deferred_comps}"; do
compdef "$func" "$cmd"
done
unset _deferred_comps
# Regenerate zcompdump if it's older than any file in fpath
DUMPFILE="${ZDOTDIR:-$HOME}/.zcompdump"
# Find the newest file across all fpath directories to detect edits/additions
# (N.om[1]) = Null-glob, plain files only, sort by mtime, pick the first (newest)
local newest_comp=(${^fpath}/*(N.om[1]))
# If any completion file was modified, or dump doesn't exist, we might need to update.
if [[ ! -f "$DUMPFILE" || ( -n "$newest_comp" && "$newest_comp" -nt "$DUMPFILE" ) ]]; then
compinit -i -d "$DUMPFILE"
# Asynchronously compile the dump file with an atomic rename
{ zcompile "$DUMPFILE.zwc.tmp" "$DUMPFILE" && mv -f "$DUMPFILE.zwc.tmp" "$DUMPFILE.zwc" } &!
else
compinit -C -i -d "$DUMPFILE"
fi
unset DUMPFILE newest_comp
autoload -Uz promptinit && promptinit
# Virtualenvwrapper
source_first_existing \
/usr/share/virtualenvwrapper/virtualenvwrapper_lazy.sh \
/usr/bin/virtualenvwrapper_lazy.sh \
/opt/homebrew/bin/virtualenvwrapper_lazy.sh
if command ls --version >/dev/null 2>&1 ; then
alias ls="$(whence -p ls) --color=auto"
fi
# Syntax highlighting and substring search
source_first_existing \
/usr/share/{,zsh/plugins/}zsh-syntax-highlighting/zsh-syntax-highlighting.zsh \
/opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
if source_if_existing ${HOME}/.zshrc.d/_zsh-history-substring-search.zsh ; then
bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down
bindkey -M vicmd 'k' history-substring-search-up
bindkey -M vicmd 'j' history-substring-search-down
fi
# Suggestions
if source_first_existing \
/usr/share/{,zsh/plugins/}zsh-autosuggestions/zsh-autosuggestions.zsh ; then
# Works well for solarized
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=10"
# Strategy -- note that 'completion' is slow AF
ZSH_AUTOSUGGEST_STRATEGY=(history)
fi
# History
alias fullhist="history 1"
alias longhist="history -1000"
# direnv if present
if command -v direnv >/dev/null 2>&1 ; then
eval "$(direnv hook zsh)"
fi
test -e "${HOME}/.iterm2_shell_integration.zsh" && \
source "${HOME}/.iterm2_shell_integration.zsh" || true
# mise, if installed
command -v mise >/dev/null 2>&1 && eval "$(mise activate zsh)"
if test -z "${PAGER}" && command -v less >/dev/null 2>&1; then
export PAGER="less"
fi
fi # End interactive-only block
# In case ack is named ack-grep
if [ -x /usr/bin/ack-grep ] ; then
alias ack='/usr/bin/ack-grep'
fi
# I want these first always
PATH="${HOME}/bin:${PATH}"
if [[ "$(uname)" == "Darwin" ]]; then
PATH="${HOME}/bin/macos:${PATH}"
elif [[ "$(uname)" == "Linux" ]]; then
PATH="${HOME}/bin/linux:${PATH}"
fi
# Load any local settings
source_if_existing $HOME/.zshrc.local
# separate interactive block based on .zshrc.local
if [[ $- == *i* ]] ; then
# Set prompt based on local settings
if test -f "${HOME}/.zprompt" ; then
THEME=${THEME:=$(cat "${HOME}/.zprompt")}
fi
if command -v starship >/dev/null 2>&1 ; then
: ${THEME:=starship}
if [ "${THEME}" = "starship" ] ; then
eval "$(starship init zsh)"
fi
fi
prompt "${THEME:-matir}" >/dev/null 2>&1
fi
# Cleanup PATH
typeset -U PATH
if [[ -n "$ZSH_PROFILE" ]]; then
zshrc_end_time=$EPOCHREALTIME
# Calculation in ms using zsh floating point math
elapsed_ms=$(( (zshrc_end_time - zshrc_start_time) * 1000 ))
printf "zshrc done: %.0fms\n" "$elapsed_ms"
zprof
fi