mirror of
https://github.com/Matir/skel.git
synced 2026-05-26 05:29:09 -07:00
322 lines
9.2 KiB
Bash
Executable File
322 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}"
|
|
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
|