mirror of
https://github.com/jakejarvis/dotfiles.git
synced 2026-06-12 17:25:26 -04:00
484 lines
15 KiB
Bash
484 lines
15 KiB
Bash
#!/usr/bin/env zsh
|
|
|
|
# set DOTFILES_DEBUG to trace startup times (1/2)
|
|
[[ "$DOTFILES_DEBUG" != "1" ]] || zmodload zsh/zprof
|
|
|
|
|
|
###########################
|
|
# Config
|
|
###########################
|
|
|
|
autoload -U colors && \
|
|
colors
|
|
|
|
autoload -Uz select-word-style && \
|
|
select-word-style bash
|
|
|
|
# autoload -Uz bracketed-paste-magic && \
|
|
# zle -N bracketed-paste bracketed-paste-magic
|
|
# zstyle ':bracketed-paste-magic' active-widgets '.self-*'
|
|
|
|
autoload -Uz url-quote-magic && \
|
|
zle -N self-insert url-quote-magic
|
|
zstyle ":urlglobber" url-other-schema ftp git gopher http https magnet
|
|
|
|
export DISABLE_MAGIC_FUNCTIONS=true # make pasting into terminal faster
|
|
|
|
# ---
|
|
|
|
setopt notify
|
|
setopt extended_history
|
|
setopt hist_expire_dups_first
|
|
setopt hist_ignore_dups
|
|
setopt hist_ignore_space
|
|
setopt hist_verify
|
|
setopt share_history
|
|
setopt inc_append_history
|
|
setopt rc_quotes
|
|
setopt extended_glob
|
|
setopt glob_dots
|
|
unsetopt case_glob
|
|
unsetopt beep
|
|
unsetopt list_beep
|
|
unsetopt correct
|
|
unsetopt correct_all
|
|
|
|
# ---
|
|
|
|
export LC_ALL="${LC_ALL:-en_US.UTF-8}"
|
|
export LANG="${LANG:-en_US.UTF-8}"
|
|
|
|
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
|
|
export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
|
|
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
|
|
|
|
export HISTFILE="${HISTFILE:-$HOME/.zsh_history}"
|
|
export HISTSIZE=10000
|
|
export SAVEHIST=10000
|
|
|
|
export EDITOR="nano"
|
|
export VISUAL="cursor --wait"
|
|
|
|
export PAGER="less"
|
|
export LESS="$LESS -RF --mouse --silent"
|
|
|
|
# resolve GPG terminal at shell runtime
|
|
# fixes "signing failed: Inappropriate ioctl for device"
|
|
if tty -s 2>/dev/null; then
|
|
GPG_TTY=$(tty)
|
|
export GPG_TTY
|
|
fi
|
|
|
|
export BROWSER="open -a 'Brave Browser'"
|
|
|
|
# https://developer.1password.com/docs/ssh/get-started#step-4-configure-your-ssh-or-git-client
|
|
if [[ -S "$HOME/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" ]]; then
|
|
export SSH_AUTH_SOCK="$HOME/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
|
|
fi
|
|
|
|
|
|
###########################
|
|
# Env vars
|
|
###########################
|
|
|
|
# homebrew tweaks
|
|
export HOMEBREW_FORCE_BREWED_CA_CERTIFICATES=1
|
|
export HOMEBREW_FORCE_BREWED_CURL=1
|
|
export HOMEBREW_FORCE_BREWED_GIT=1
|
|
export HOMEBREW_NO_ANALYTICS=1
|
|
export HOMEBREW_NO_ENV_HINTS=1
|
|
export HOMEBREW_NO_INSECURE_REDIRECT=1
|
|
|
|
# docker tweaks
|
|
export DOCKER_BUILDKIT=1
|
|
export DOCKER_SCAN_SUGGEST=false
|
|
|
|
# npm tweaks
|
|
export DISABLE_OPENCOLLECTIVE=1
|
|
export NO_UPDATE_NOTIFIER=1
|
|
export NPM_CONFIG_FUND=false
|
|
export NPM_CONFIG_UPDATE_NOTIFIER=false
|
|
export OPEN_SOURCE_CONTRIBUTOR=true
|
|
export OPENCOLLECTIVE_HIDE=1
|
|
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
|
export MISE_NODE_COREPACK=1
|
|
|
|
# can everyone stop being so creepy pls
|
|
export DO_NOT_TRACK=1
|
|
export AZURE_CORE_COLLECT_TELEMETRY=0
|
|
export CHECKPOINT_DISABLE=1
|
|
export CLI_COLLECT_METRICS=0
|
|
export GATSBY_TELEMETRY_DISABLED=1
|
|
export NEXT_TELEMETRY_DISABLED=1
|
|
export TURBO_TELEMETRY_DISABLED=1
|
|
export YARN_ENABLE_TELEMETRY=0
|
|
|
|
|
|
###########################
|
|
# Path
|
|
###########################
|
|
|
|
# Homebrew's location is different depending on OS...
|
|
# https://github.com/Homebrew/install/blob/master/install.sh#L122
|
|
if [[ -d /opt/homebrew ]]; then
|
|
# macOS on Apple Silicon
|
|
BREW_BIN="/opt/homebrew/bin/brew"
|
|
elif [[ -d "$HOME/.linuxbrew" ]]; then
|
|
# Linux, user install
|
|
# NOTE: definitely discouraged, maybe deprecated? https://github.com/Homebrew/install/pull/702
|
|
BREW_BIN="$HOME/.linuxbrew/bin/brew"
|
|
elif [[ -d /home/linuxbrew/.linuxbrew ]]; then
|
|
# Linux, system install
|
|
BREW_BIN="/home/linuxbrew/.linuxbrew/bin/brew"
|
|
else
|
|
# macOS on Intel (hopefully, or else we're kinda doomed...)
|
|
BREW_BIN="/usr/local/bin/brew"
|
|
fi
|
|
|
|
# set PATHs for Homebrew (if we found it)
|
|
if [[ -x "$BREW_BIN" ]]; then
|
|
eval "$("$BREW_BIN" shellenv)"
|
|
fi
|
|
|
|
# go
|
|
if [[ -d "$HOME/golang" ]]; then
|
|
export GOPATH="$HOME/golang"
|
|
path=("$GOPATH/bin" $path)
|
|
fi
|
|
|
|
# rust/cargo
|
|
if [[ -d "$HOME/.cargo" ]]; then
|
|
path=("$HOME/.cargo/bin" $path)
|
|
fi
|
|
|
|
# mise
|
|
if command -v mise &>/dev/null; then
|
|
eval "$(mise activate zsh)"
|
|
fi
|
|
|
|
# rbenv
|
|
if command -v rbenv &>/dev/null; then
|
|
eval "$(rbenv init - --no-rehash zsh)"
|
|
fi
|
|
|
|
# bun
|
|
if [[ -d "$HOME/.cache/.bun" ]]; then
|
|
path=("$HOME/.cache/.bun/bin" $path)
|
|
fi
|
|
|
|
# XDG-standard user bin (uv, pipx, cargo-installed binaries, etc.)
|
|
if [[ -d "$HOME/.local/bin" ]]; then
|
|
path=("$HOME/.local/bin" $path)
|
|
fi
|
|
|
|
# docker user mode, see: https://docs.docker.com/desktop/mac/permission-requirements/#installing-symlinks
|
|
if [[ -d "$HOME/.docker/bin" ]]; then
|
|
path=("$HOME/.docker/bin" $path)
|
|
fi
|
|
|
|
# orbstack
|
|
if [[ -d "$HOME/.orbstack" ]]; then
|
|
source "$HOME/.orbstack/shell/init.zsh" 2>/dev/null || :
|
|
fi
|
|
|
|
# Vite+ bin (https://viteplus.dev)
|
|
if [[ -d "$HOME/.vite-plus" ]]; then
|
|
source "$HOME/.vite-plus/env"
|
|
fi
|
|
|
|
# let zsh sort out formatting and deduplication
|
|
typeset -aU path fpath manpath
|
|
export PATH FPATH MANPATH
|
|
|
|
|
|
###########################
|
|
# Tools
|
|
###########################
|
|
|
|
# bat (better cat)
|
|
if command -v bat &>/dev/null; then
|
|
export BAT_THEME="base16"
|
|
export MANPAGER='sh -c "col -bx | bat --color=always --style=plain --language=man"'
|
|
fi
|
|
|
|
# fzf: env vars first, then source brew-shipped key-bindings
|
|
if command -v fzf &>/dev/null; then
|
|
export FZF_FD_OPTS="--color always --hidden --follow --exclude .git --exclude node_modules"
|
|
export FZF_PREVIEW_FILE_COMMAND="bat --color=always --paging=never --style=plain"
|
|
export FZF_PREVIEW_DIR_COMMAND="eza -1a --color=always --icons --group-directories-first"
|
|
export FZF_DEFAULT_OPTS="--cycle --select-1 --exit-0 --height=60% --no-mouse --bind=\"tab:accept,ctrl-y:preview-page-up,ctrl-v:preview-page-down,ctrl-e:execute-silent(\${VISUAL:-\$EDITOR} {+} >/dev/null 2>&1)\""
|
|
export FZF_DEFAULT_COMMAND="fd --type f $FZF_FD_OPTS"
|
|
export FZF_ALT_C_OPTS="-i --ansi --preview=\"$FZF_PREVIEW_DIR_COMMAND {}\""
|
|
export FZF_ALT_C_COMMAND="fd --type d . $FZF_FD_OPTS"
|
|
export FZF_CTRL_T_OPTS="-i --ansi --bind=\"ctrl-w:execute(\$EDITOR {1} >/dev/tty </dev/tty)+refresh-preview\" --preview=\"$FZF_PREVIEW_FILE_COMMAND {} 2>/dev/null\""
|
|
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
|
|
|
|
[[ -n "$HOMEBREW_PREFIX" && -f "$HOMEBREW_PREFIX/opt/fzf/shell/key-bindings.zsh" ]] && \
|
|
source "$HOMEBREW_PREFIX/opt/fzf/shell/key-bindings.zsh"
|
|
fi
|
|
|
|
|
|
###########################
|
|
# Aliases
|
|
###########################
|
|
|
|
# allow sudo-able aliases
|
|
alias sudo="sudo "
|
|
|
|
# colorful ls (prefer eza if available)
|
|
if command -v eza &>/dev/null; then
|
|
alias ls='eza --color=auto -GF --icons --group-directories-first'
|
|
alias ll='eza --color=auto -1laF --git --icons --group-directories-first --ignore-glob=".DS_Store*|~*"'
|
|
alias lt='ll -T -L=2'
|
|
else
|
|
alias ls="ls -G --color=auto"
|
|
alias ll="ls -lah"
|
|
fi
|
|
alias la="ls -a"
|
|
alias l="ll"
|
|
|
|
# git
|
|
alias gc="git commit -m" # + commit message
|
|
alias gca="git add -A && git commit -m" # + commit message
|
|
alias gs="git status -sb"
|
|
alias gl="git log --pretty=short"
|
|
alias gd="git diff"
|
|
alias gds="git diff --staged"
|
|
alias gpom="git push origin main"
|
|
alias glom="git pull origin main"
|
|
alias gpo="git push origin" # + branch name
|
|
alias glo="git pull origin" # + branch name
|
|
alias glfm="git fetch && git reset origin/main --hard"
|
|
alias gb="git checkout" # + existing branch name
|
|
alias gbn="git checkout -b" # + new branch name
|
|
alias grm="git rebase -i origin/main"
|
|
alias gsub="git submodule update --recursive --remote"
|
|
alias gundo="git reset --soft HEAD~1"
|
|
alias gres="git reset"
|
|
alias github="gh repo view --web"
|
|
alias gist="gh gist create --web"
|
|
if command -v lazygit &>/dev/null; then
|
|
alias lg="lazygit"
|
|
fi
|
|
|
|
# docker
|
|
alias dps="docker ps -a"
|
|
dbar() {
|
|
# build a Dockerfile in the current directory and run it interactively:
|
|
# https://stackoverflow.com/questions/45141402/build-and-run-dockerfile-with-one-command/59220656#59220656
|
|
docker run --rm -it "$(docker build --no-cache -q .)"
|
|
}
|
|
dsh() {
|
|
docker exec -it "$1" /bin/sh
|
|
}
|
|
alias dc="docker compose"
|
|
alias dcu="dc up -d"
|
|
alias dcd="dc down"
|
|
alias dcr="dcd && dcu"
|
|
alias dcl="dc logs -f"
|
|
|
|
# open current working directory in VS Code
|
|
alias vs="code ."
|
|
|
|
# an original creation, see https://github.com/jakejarvis/simpip
|
|
alias ipv4="curl -4 simpip.com --max-time 1 --proto-default https --silent"
|
|
alias ipv6="curl -6 simpip.com --max-time 1 --proto-default https --silent"
|
|
alias ip="ipv4; ipv6"
|
|
alias ips="ip; ifconfig -a | grep -o 'inet6\? \(addr:\)\?\s\?\(\(\([0-9]\+\.\)\{3\}[0-9]\+\)\|[a-fA-F0-9:]\+\)' | awk '{ sub(/inet6? (addr:)? ?/, \"\"); print }'"
|
|
|
|
# youtube-dl
|
|
alias youtube-dl="yt-dlp" # better youtube-dl fork: https://github.com/yt-dlp/yt-dlp
|
|
alias ytdl="youtube-dl -f bestvideo+bestaudio"
|
|
alias ytmp3="youtube-dl -f bestaudio -x --audio-format mp3 --audio-quality 320K"
|
|
|
|
# open current directory in Finder
|
|
alias finder="open -a Finder ."
|
|
|
|
# convenient access to ssh public key
|
|
alias pubkey="pbcopy < ~/.ssh/id_ed25519.pub && echo '=> Public key copied to clipboard.'"
|
|
|
|
# workaround for lack of tailscale CLI on mac:
|
|
# https://tailscale.com/kb/1080/cli/?tab=macos#using-the-cli
|
|
alias tailscale="/Applications/Tailscale.app/Contents/MacOS/Tailscale"
|
|
|
|
# slop stats
|
|
alias ccusage="bunx ccusage@latest"
|
|
alias cxusage="bunx @ccusage/codex@latest"
|
|
alias ocusage="bunx @ccusage/opencode@latest"
|
|
|
|
|
|
###########################
|
|
# Plugins
|
|
###########################
|
|
|
|
# these custom values must be set *before* sourcing zinit
|
|
export ZINIT_HOME="${ZINIT_HOME:-"${XDG_DATA_HOME:-"${HOME}/.local/share"}/zinit/zinit.git"}"
|
|
declare -A ZINIT=(
|
|
[ZCOMPDUMP_PATH]="${XDG_CACHE_HOME:-"$HOME/.cache"}/zsh/.zcompdump-$ZSH_VERSION"
|
|
)
|
|
|
|
# check for zinit
|
|
if [[ -f "$ZINIT_HOME/zinit.zsh" ]]; then
|
|
source "$ZINIT_HOME/zinit.zsh"
|
|
else
|
|
echo "zinit not found in '$ZINIT_HOME', either check the value of ZINIT_HOME or install zinit."
|
|
return
|
|
fi
|
|
|
|
# initialize zinit && ensure compinit recognizes its completions
|
|
autoload -Uz _zinit
|
|
(( ${+_comps} )) && _comps[zinit]=_zinit
|
|
|
|
# various zinit add-ons
|
|
zinit light zdharma-continuum/zinit-annex-patch-dl
|
|
|
|
# oh-my-zsh was good at setting iTerm tab titles, keep doing it pls
|
|
# https://github.com/ohmyzsh/ohmyzsh/tree/master/lib
|
|
zinit snippet OMZ::lib/functions.zsh
|
|
zinit snippet OMZ::lib/termsupport.zsh
|
|
|
|
# grab vivid binary (for all the colors)
|
|
# https://github.com/sharkdp/vivid/tree/master/themes
|
|
# by outputting the generated LS_COLORS variable to a file and sourcing it, we only need to call vivid once on
|
|
# installation rather than every time a new session begins.
|
|
zinit ice lucid from"gh-r" as"command" \
|
|
atclone'
|
|
local -a bin
|
|
bin=(vivid-*/vivid(N))
|
|
(( $#bin )) && mv -f -- "$bin[1]" vivid
|
|
[[ -x ./vivid ]] || return
|
|
|
|
local ls_colors
|
|
ls_colors="$(./vivid generate snazzy)" || return
|
|
print -r -- "export LS_COLORS=${(qqq)ls_colors}" > colors.zsh
|
|
' \
|
|
atpull"%atclone" \
|
|
atload"zstyle ':completion:*' list-colors \${(s.:.)LS_COLORS}" \
|
|
src"colors.zsh"
|
|
zinit light sharkdp/vivid
|
|
|
|
# tab completions via fzf
|
|
zinit ice wait"0b" lucid depth"1" \
|
|
has"fzf" \
|
|
blockf \
|
|
atpull"zinit creinstall -q ." \
|
|
atload"
|
|
zstyle ':completion:*' verbose true
|
|
zstyle ':completion:*' cache-path '$(dirname ${ZINIT[ZCOMPDUMP_PATH]})/.zcompcache'
|
|
zstyle ':completion:*' menu select
|
|
zstyle ':completion:*' group-name ''
|
|
zstyle ':completion:*' select-prompt '%SScrolling active: current selection at %p%s'
|
|
zstyle ':completion:*:descriptions' format '%d'
|
|
zstyle ':completion:*:functions' ignored-patterns '_*'
|
|
zstyle ':completion::complete:*:*:files' ignored-patterns '.DS_Store' 'Icon?'
|
|
zstyle ':completion::complete:*:*:globbed-files' ignored-patterns '.DS_Store' 'Icon?'
|
|
zstyle ':completion::complete:rm:*:globbed-files' ignored-patterns
|
|
zstyle ':fzf-tab:*' fzf-command 'fzf'
|
|
zstyle ':fzf-tab:*' fzf-flags $FZF_DEFAULT_OPTS '-i' '--ansi'
|
|
zstyle ':fzf-tab:*' fzf-bindings \
|
|
'tab:accept' \
|
|
'ctrl-y:preview-page-up' \
|
|
'ctrl-v:preview-page-down' \
|
|
'ctrl-e:execute-silent(\${VISUAL:-\$EDITOR} \$realpath >/dev/null 2>&1)' \
|
|
'ctrl-w:execute(\$EDITOR \$realpath >/dev/tty </dev/tty)+refresh-preview'
|
|
zstyle ':fzf-tab:*' fzf-min-height 15
|
|
zstyle ':fzf-tab:complete:git-(add|diff|restore):*' fzf-preview \
|
|
'git diff --no-ext-diff \$word | delta --paging=never --no-gitconfig --line-numbers --file-style=omit --hunk-header-style=omit --theme=base16'
|
|
zstyle ':fzf-tab:complete:git-log:*' fzf-preview \
|
|
'git --no-pager log --color=always --format=oneline --abbrev-commit --follow \$word'
|
|
zstyle ':fzf-tab:complete:man:*' fzf-preview \
|
|
'man -P \"col -bx\" \$word | $FZF_PREVIEW_FILE_COMMAND --language=man'
|
|
zstyle ':fzf-tab:complete:brew-(install|uninstall|search|info):*-argument-rest' fzf-preview \
|
|
'brew info \$word'
|
|
zstyle ':fzf-tab:complete:*:options' fzf-preview
|
|
zstyle ':fzf-tab:complete:*:options' fzf-flags '--no-preview'
|
|
zstyle ':fzf-tab:complete:*:argument-1' fzf-preview
|
|
zstyle ':fzf-tab:complete:*:argument-1' fzf-flags '--no-preview'
|
|
zstyle ':fzf-tab:complete:*:*' fzf-preview \
|
|
'($FZF_PREVIEW_FILE_COMMAND \$realpath || $FZF_PREVIEW_DIR_COMMAND \$realpath) 2>/dev/null'
|
|
"
|
|
zinit light Aloxaf/fzf-tab
|
|
|
|
# macOS-only completion fixes
|
|
zinit ice wait lucid as"null" \
|
|
id-as"_local/extra/mac" \
|
|
if'[[ "$OSTYPE" = darwin* ]]' \
|
|
atload"
|
|
zstyle ':completion:*:*:*:*:processes' command 'ps -o comm=\"\" -w -w'
|
|
zstyle ':fzf-tab:complete:(kill|ps):argument-rest' fzf-preview \
|
|
'[[ \$group == \"process ID\" ]] && ps -p\$word -o comm=\"\" -w -w'
|
|
"
|
|
zinit light zdharma-continuum/null
|
|
|
|
# Linux-only completion fixes
|
|
zinit ice wait lucid as"null" \
|
|
id-as"_local/extra/linux" \
|
|
if'[[ "$OSTYPE" = linux-gnu* ]]' \
|
|
atload"
|
|
zstyle ':completion:*:*:*:*:processes' command 'ps -o cmd --no-headers -w -w'
|
|
zstyle ':fzf-tab:complete:(kill|ps):argument-rest' fzf-preview \
|
|
'[[ \$group == \"process ID\" ]] && ps --pid=\$word -o cmd --no-headers -w -w'
|
|
zstyle ':fzf-tab:complete:systemctl-*:*' fzf-preview 'SYSTEMD_COLORS=1 systemctl status \$word'
|
|
"
|
|
zinit light zdharma-continuum/null
|
|
|
|
# autopairing of quotes, brackets, etc.
|
|
zinit ice wait"0b" lucid depth"1" \
|
|
atload"ZSH_AUTOSUGGEST_CLEAR_WIDGETS+=(autopair-insert)"
|
|
zinit light hlissner/zsh-autopair
|
|
|
|
# syntax highlighting
|
|
zinit ice wait lucid depth"1" \
|
|
atinit"ZINIT[COMPINIT_OPTS]=-C; zicompinit; zicdreplay" \
|
|
atload"
|
|
zle_highlight+=('paste:reverse')
|
|
zstyle ':plugin:fast-syntax-highlighting' theme ''
|
|
typeset -gA FAST_HIGHLIGHT_STYLES
|
|
FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME:-}variable]='fg=cyan,bold'
|
|
"
|
|
zinit light zdharma-continuum/fast-syntax-highlighting
|
|
|
|
# autosuggestions, trigger precmd hook upon load
|
|
zinit ice wait"0a" lucid depth"1" \
|
|
atinit"
|
|
export ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=60
|
|
export ZSH_AUTOSUGGEST_USE_ASYNC=1
|
|
" \
|
|
atload"_zsh_autosuggest_start"
|
|
zinit light zsh-users/zsh-autosuggestions
|
|
|
|
# 1Password plugins: https://developer.1password.com/docs/cli/shell-plugins/
|
|
zinit ice wait"1" lucid \
|
|
id-as"_local/op-auth" \
|
|
has"op" \
|
|
if"[[ -f ~/.config/op/plugins.sh ]]" \
|
|
nocompile
|
|
zinit snippet ~/.config/op/plugins.sh
|
|
|
|
# iTerm2 integration
|
|
zinit ice lucid depth"1" \
|
|
if'[[ "$TERM_PROGRAM" = "iTerm.app" ]]' \
|
|
atload'path=("$(pwd)/utilities" $path)' \
|
|
src"shell_integration/zsh" \
|
|
nocompile
|
|
zinit light gnachman/iTerm2-shell-integration
|
|
|
|
# starship prompt (binary + completion shipped by brew, init script cached here)
|
|
zinit ice has"starship" \
|
|
id-as"_local/starship-init" \
|
|
atclone"starship init zsh --print-full-init > init.zsh; zcompile init.zsh" \
|
|
atpull"%atclone" \
|
|
src"init.zsh" \
|
|
nocompile
|
|
zinit light zdharma-continuum/null
|
|
|
|
|
|
##############################
|
|
|
|
if [[ -f ~/.zshrc.local ]]; then
|
|
source ~/.zshrc.local
|
|
fi
|
|
|
|
# uncomment to debug startup time (2/2)
|
|
[[ "$DOTFILES_DEBUG" != "1" ]] || zprof
|