zsh/.zshrc

# ~/.zshrc -- see mercemay.top/src/dotfiles/
# This file runs for interactive shells. Login-only stuff goes in .zprofile.

# ---- path -------------------------------------------------------------
typeset -U path PATH
path=(
	"$HOME/.local/bin"
	"$HOME/bin"
	"$HOME/go/bin"
	"$HOME/.cargo/bin"
	/opt/homebrew/bin
	/usr/local/bin
	$path
)
export PATH

export EDITOR=nvim
export VISUAL=nvim
export PAGER=less
export LESS='-R -F -X --mouse --wheel-lines=3'
export MANPAGER='nvim +Man!'

# ---- history ----------------------------------------------------------
HISTFILE="$HOME/.cache/zsh/history"
HISTSIZE=200000
SAVEHIST=200000
mkdir -p "${HISTFILE:h}"
setopt APPEND_HISTORY
setopt EXTENDED_HISTORY
setopt HIST_IGNORE_ALL_DUPS
setopt HIST_IGNORE_SPACE
setopt HIST_REDUCE_BLANKS
setopt HIST_VERIFY
setopt INC_APPEND_HISTORY
setopt SHARE_HISTORY

# ---- options ----------------------------------------------------------
setopt AUTO_CD
setopt AUTO_PUSHD
setopt PUSHD_IGNORE_DUPS
setopt PUSHD_SILENT
setopt EXTENDED_GLOB
setopt NO_BEEP
setopt INTERACTIVE_COMMENTS
setopt PROMPT_SUBST

# ---- completion -------------------------------------------------------
fpath=(
	"$HOME/.dotfiles/zsh/completions"
	/opt/homebrew/share/zsh/site-functions
	$fpath
)

autoload -Uz compinit
zcompdump="$HOME/.cache/zsh/compdump"
if [[ -n "$zcompdump"(#qNmh+24) ]]; then
	compinit -d "$zcompdump"
else
	compinit -C -d "$zcompdump"
fi

zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*:descriptions' format '%F{yellow}%d%f'
zstyle ':completion:*' group-name ''

# ---- keybindings ------------------------------------------------------
bindkey -e
bindkey '^R' history-incremental-search-backward
bindkey '^[[A' up-line-or-search
bindkey '^[[B' down-line-or-search
bindkey '^[.' insert-last-word

# ---- plugins (manual, no framework) -----------------------------------
plugdir="$HOME/.cache/zsh/plugins"
mkdir -p "$plugdir"
_load_plugin() {
	local name="$1" url="$2" entry="$3"
	local dest="$plugdir/$name"
	if [[ ! -d "$dest" ]]; then
		git clone --depth=1 -q "$url" "$dest" || return
	fi
	[[ -f "$dest/$entry" ]] && source "$dest/$entry"
}
_load_plugin zsh-syntax-highlighting \
	https://github.com/zsh-users/zsh-syntax-highlighting.git \
	zsh-syntax-highlighting.zsh
_load_plugin zsh-autosuggestions \
	https://github.com/zsh-users/zsh-autosuggestions.git \
	zsh-autosuggestions.zsh
_load_plugin fzf-tab \
	https://github.com/Aloxaf/fzf-tab.git \
	fzf-tab.plugin.zsh

ZSH_AUTOSUGGEST_STRATEGY=(history completion)
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=20
zstyle ':fzf-tab:*' use-fzf-default-opts yes
zstyle ':fzf-tab:complete:*:*' fzf-preview \
	'[[ -d $realpath ]] && ls --color=always $realpath || bat --style=plain --color=always $realpath 2>/dev/null || head -200 $realpath'

# ---- fzf --------------------------------------------------------------
if command -v fzf >/dev/null 2>&1; then
	if [[ -f /opt/homebrew/opt/fzf/shell/key-bindings.zsh ]]; then
		source /opt/homebrew/opt/fzf/shell/key-bindings.zsh
	elif [[ -f /usr/share/doc/fzf/examples/key-bindings.zsh ]]; then
		source /usr/share/doc/fzf/examples/key-bindings.zsh
	fi
	export FZF_DEFAULT_OPTS='--height=40% --layout=reverse --border --info=inline'
	export FZF_DEFAULT_COMMAND='rg --files --hidden --follow --glob=!.git'
fi

# ---- direnv -----------------------------------------------------------
if command -v direnv >/dev/null 2>&1; then
	eval "$(direnv hook zsh)"
fi

# ---- zoxide -----------------------------------------------------------
if command -v zoxide >/dev/null 2>&1; then
	eval "$(zoxide init zsh)"
fi

# ---- prompt -----------------------------------------------------------
if command -v starship >/dev/null 2>&1; then
	eval "$(starship init zsh)"
else
	PROMPT='%F{cyan}%~%f %F{green}%#%f '
fi

# ---- aliases & functions ---------------------------------------------
[[ -f "$HOME/.aliases.zsh" ]] && source "$HOME/.aliases.zsh"

# ---- per-host override ------------------------------------------------
[[ -f "$HOME/.zshrc.local" ]] && source "$HOME/.zshrc.local"