dotfiles/.zshrc
2025-11-18 10:59:03 +10:00

308 lines
7.6 KiB
Bash

#!/usr/bin/env zsh
unsetopt prompt_cr prompt_sp
unsetopt LIST_BEEP
### BREW
export BREW_PREFIX="/opt/homebrew"
export MANPATH="/opt/homebrew/share/man:$MANPATH"
export INFOPATH="/opt/homebrew/share/info:$INFOPATH"
### FZF
source "$BREW_PREFIX/opt/fzf/shell/key-bindings.zsh"
do_cd_fzf() {
local parent="$1"
cd "${parent}/$(find "${parent}" \
-maxdepth 1 \
-mindepth 1 \
-type d | \
xargs -I '{}' basename '{}' | \
fzf --height 10% --color=light,hl:196,hl+:196)"
}
do_edit_fzf() {
local dir="$1"
pushd "$dir" 2>&1 1>/dev/null
local target="$(fzf)"
if [ "${target}" != "" ]; then
sh -c "$EDITOR '${target}'"
fi
popd 2>&1 1>/dev/null
}
do_checkout() {
git for-each-ref --format='%(refname:short)' refs/heads | fzf --height 10% --color=light,hl:196,hl+:196 | xargs -r git checkout
}
export FZF_DEFAULT_COMMAND='agcmd'
export FZF_DEFAULT_OPTS="--color=light,hl:196,hl+:196"
export FZF_TAB_GROUP_COLORS=(
$'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' \
$'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' \
$'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m'
)
### PRIVATES
[ -f "${HOME}/.config/private/zsh.zsh" ] && source "${HOME}/.config/private/zsh.zsh"
### HELPERS
function uber_download {
lftp -e "pget -c -n128 \"$1\"; quit"
}
function ppwd {
pwd | pbcopy
}
function gdifftool {
local target="$1"
local changes="$(git status --porcelain=v1 2>/dev/null | wc -l)"
if [ "$changes" -gt 0 ]; then
git difftool
elif [ "$target" = "" ]; then
git difftool $(git branch --no-color --show-current) origin/$(git branch --no-color --show-current)
else
git difftool $(git branch --no-color --show-current) $target
fi
}
### COMPLETIONS
autoload -Uz compinit
compinit -C
# Add Homebrew completions to fpath
fpath=("$BREW_PREFIX/share/zsh/site-functions" $fpath)
### SETTINGS
setopt noautomenu
setopt nomenucomplete
setopt nolistambiguous
setopt bash_auto_list
unsetopt auto_menu
unsetopt menu_complete
unsetopt list_ambiguous
setopt no_list_beep
### MUST. GO. FAST.
unsetopt AUTO_CD
unsetopt AUTO_PUSHD
unsetopt PUSHD_IGNORE_DUPS
unsetopt PUSHD_MINUS
unsetopt PUSHD_SILENT
unsetopt PUSHD_TO_HOME
unsetopt FLOW_CONTROL
unsetopt BEEP
zstyle ':completion:*' accept-exact '*(N)'
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path ~/.zsh/cache
zstyle ':completion:*' menu no
export EDITOR='nvim'
export GIT_EDITOR='nvim'
export TEXEDIT='nvim'
export LESSEDIT='nvim'
export VISUAL='nvim'
### ENV CONFIG
export PATH="${HOME}/.local/bin:/opt/homebrew/bin:/opt/homebrew/sbin:${HOME}/.cargo/bin:/opt/homebrew/opt/rustup/bin:/Applications/IntelliJ IDEA.app/Contents/MacOS:/usr/local/bin:${GOROOT}/bin:$PATH"
export TMPDIR=$(getconf DARWIN_USER_TEMP_DIR)
### ALIASES
alias n='npm'
alias d='docker'
alias D='lazydocker'
alias dps='docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Names}}"'
alias k='kubectl'
alias src="do_cd_fzf ~/src"
alias vim="nvim"
alias vimdiff="nvim -d"
alias bb="bbedit"
alias bw="bbedit --wait --resume"
alias ls="eza --group-directories-first --header"
alias lg="lazygit"
alias rm=trash
alias gst="git status"
alias gwt="git worktree"
alias gdf="gdifftool"
alias fuck="init_thefuck"
alias nvm="fnm"
### KEYS
bindkey -s '\C-g\C-b' 'do_checkout\n'
# Home/End keys
bindkey '\e[H' beginning-of-line
bindkey '\e[F' end-of-line
# Alt+Left/Right for word movement
bindkey '\e[1;3D' backward-word
bindkey '\e[1;3C' forward-word
### HISTORY
HISTFILE="$HOME/.zsh_history"
HISTSIZE=50000
SAVEHIST=50000
setopt BANG_HIST # Treat the '!' character specially during expansion.
setopt EXTENDED_HISTORY # Write the history file in the ":start:elapsed;command" format.
setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits.
setopt SHARE_HISTORY # Share history between all sessions.
setopt HIST_EXPIRE_DUPS_FIRST # Expire duplicate entries first when trimming history.
setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again.
setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate.
setopt HIST_FIND_NO_DUPS # Do not display a line previously found.
setopt HIST_IGNORE_SPACE # Don't record an entry starting with a space.
setopt HIST_SAVE_NO_DUPS # Don't write duplicate entries in the history file.
setopt HIST_REDUCE_BLANKS # Remove superfluous blanks before recording entry.
setopt HIST_VERIFY # Don't execute immediately upon history expansion.
setopt HIST_BEEP # Beep when accessing nonexistent history.
### CUSTOMIZATION
setopt PROMPT_SUBST
function prompt_color {
if [ "$EUID" -eq 0 ]; then
printf '\033[31m' # Red for root
else
printf '\033[38;5;24m' # Blue for regular user
fi
}
function prompt_text {
if [ "$EUID" -eq 0 ]; then
printf '[***ROOT***] # '
else
printf '%%f􀣺 '
fi
}
function git_ps1 {
# Exit if not in git repo
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
return
fi
# Use cached branch info
if [[ -n $GIT_BRANCH_CACHE ]]; then
echo -n "($GIT_BRANCH_CACHE)"
else
local branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
if [[ -n $branch && $branch != "HEAD" ]]; then
export GIT_BRANCH_CACHE="$branch"
echo -n "($branch)"
fi
fi
}
function shorten_path {
local current_path=$(pwd)
local last=$(echo $current_path | sed -e 's/[^\/]*\///g')
local path=""
[[ $current_path == "$HOME"* ]] && path="~"
current_path=${current_path/"$HOME"/''}
current_path=${current_path:1}
# macOS-compatible array splitting
current_path=(${(s:/:)current_path})
for x in $current_path
do
if [ "$x" = "$last" ];
then
path="${path}/${x}"
else
path="${path}/${x:0:1}"
fi
done
echo $path
}
export PS1='%F{cyan}[$(shorten_path)]%F{red}$(git_ps1)
%F{cyan}$(prompt_text)%f'
### THE FUCK (lazilly)
function init_thefuck() {
unalias fuck
unset -f init_thefuck
eval $(thefuck --alias)
fuck
}
### NODE
eval "$(fnm env --use-on-cd --shell zsh)"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
corepack enable
### DOCKER
if command -v docker &> /dev/null; then
fpath=("$HOME/.docker/completions" $fpath)
fi
### KUBE
if command -v kubectl &> /dev/null; then
source <(kubectl completion zsh)
fi
### GO
export GOROOT="/opt/homebrew/opt/golang/libexec"
export GOPATH="${HOME}/src/go"
export PATH="${GOPATH}/bin:${PATH}"
### PYTHON
function load_pyenv() {
if command -v pyenv &> /dev/null; then
eval "$(pyenv init --path)"
eval "$(pyenv init - --no-rehash)"
if which pyenv-virtualenv-init > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi
pyenv virtualenvwrapper
unset -f load_pyenv
fi
}
# Only load pyenv when needed
alias pyenv='load_pyenv && pyenv'
### RUBY
export RUBY_VERSION=3.3.0
export GEM_HOME=$HOME/.gem
export PATH=$GEM_HOME/bin:$PATH
export PATH=$GEM_HOME/ruby/$RUBY_VERSION/bin:$PATH
### HOOKS
autoload -U add-zsh-hook
maybe_nvm_after_cd() {
local dir
dir=$(pwd)
while [ "$dir" != "/" ]; do
if [ -f "$dir/.nvmrc" ]; then
if type load_nvm >/dev/null 2>&1; then
load_nvm
fi
nvm use 2>/dev/null || true
return
fi
dir=$(dirname "$dir")
done
}
function git_branch_cache_clear() {
unset GIT_BRANCH_CACHE
}
add-zsh-hook chpwd maybe_nvm_after_cd
add-zsh-hook chpwd git_branch_cache_clear
#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
export SDKMAN_DIR="$HOME/.sdkman"
[[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh"