mirror of
https://github.com/jimeh/dotfiles.git
synced 2026-02-19 11:46:40 +00:00
Biggest change is embracing fzf for all shell completion. This includes using tmux popup windows to effectively render completions as floating popups with fuzzy matching via fzf. Shell history has also been improved, with appending each command to the history file one by one, rather than only at end of a shell session when the shell exists. This should ensure I don't have any more lost commands cause the shell didn't exit cleanly.
307 lines
10 KiB
Bash
307 lines
10 KiB
Bash
#
|
|
# Z-Shell Init
|
|
#
|
|
|
|
# In our zshenv file we have on macOS disabled loading ZSH startup files from
|
|
# /etc to avoid /etc/zprofile messing up our carefully constructed PATH. So we
|
|
# need to manually load the other files we care about.
|
|
if [[ "$OSTYPE" == "darwin"* ]] && [ -f "/etc/zshrc" ]; then
|
|
source "/etc/zshrc"
|
|
fi
|
|
|
|
# ==============================================================================
|
|
# Zinit
|
|
# ==============================================================================
|
|
|
|
declare -A ZINIT
|
|
ZINIT[HOME_DIR]="$HOME/.local/zsh/zinit"
|
|
ZINIT[BIN_DIR]="${ZINIT[HOME_DIR]}/bin"
|
|
|
|
# Load zinit module if it exists. For more info, run: zinit module help
|
|
if [ -d "${ZINIT[HOME_DIR]}/module/Src/zdharma_continuum" ]; then
|
|
module_path+=("${ZINIT[HOME_DIR]}/module/Src")
|
|
zmodload zdharma_continuum/zinit
|
|
fi
|
|
|
|
# Ask to clone Zinit if it's not already available on disk.
|
|
[ ! -d "${ZINIT[BIN_DIR]}" ] &&
|
|
read -q "REPLY?Zinit not installed, clone to ${ZINIT[BIN_DIR]}? [y/N]:" &&
|
|
echo &&
|
|
git clone --depth=1 "https://github.com/zdharma-continuum/zinit.git" "${ZINIT[BIN_DIR]}"
|
|
|
|
# Load Zinit
|
|
source "${ZINIT[BIN_DIR]}/zinit.zsh"
|
|
|
|
# ==============================================================================
|
|
# History
|
|
# ==============================================================================
|
|
|
|
# Set various sane defaults for ZSH history management.
|
|
zinit for @OMZ::lib/history.zsh
|
|
|
|
# Map history search to ctrl-p and ctrl-n.
|
|
# bindkey '^p' history-beginning-search-backward
|
|
# bindkey '^n' history-beginning-search-forward
|
|
|
|
## History file configuration
|
|
HISTFILE="$HOME/.zsh_history"
|
|
HISTSIZE=100000
|
|
SAVEHIST=50000
|
|
|
|
## History command configuration
|
|
setopt append_history # append history to HISTFILE
|
|
setopt extended_history # record timestamp of command in HISTFILE
|
|
setopt hist_expire_dups_first # delete duplicates first when HISTFILE size exceeds HISTSIZE
|
|
setopt hist_find_no_dups # do not display a duplicate history entry
|
|
setopt hist_ignore_dups # ignore duplicated commands history list
|
|
setopt hist_ignore_space # ignore commands that start with space
|
|
setopt hist_reduce_blanks # remove superfluous blanks before adding to history
|
|
setopt hist_verify # show command with history expansion to user before running it
|
|
setopt inc_append_history_time # add timestamp to HISTFILE in order of execution
|
|
setopt share_history # share command history data
|
|
|
|
# ==============================================================================
|
|
# Completion
|
|
# ==============================================================================
|
|
|
|
if [ -d "$ZSH_COMPLETIONS" ]; then fpath=("$ZSH_COMPLETIONS" $fpath); fi
|
|
if [ -d "$DOTZSH_SITEFUNS" ]; then fpath=("$DOTZSH_SITEFUNS" $fpath); fi
|
|
if [ -d "$BREW_SITEFUNS" ]; then fpath=("$BREW_SITEFUNS" $fpath); fi
|
|
|
|
# Enable interactive selection of completions.
|
|
zinit for @OMZ::lib/completion.zsh
|
|
|
|
# Add generic cross platform clipcopy and clippaste commands to copy and paste
|
|
# from the system clipboard.
|
|
zinit for @OMZ::lib/clipboard.zsh
|
|
|
|
# Install fzf-tab if fzf is available.
|
|
if command-exists fzf; then
|
|
zinit light-mode wait lucid for @Aloxaf/fzf-tab
|
|
zinit light-mode wait lucid for @Freed-Wu/fzf-tab-source
|
|
fi
|
|
|
|
zinit light-mode wait lucid blockf for @zsh-users/zsh-completions
|
|
|
|
zinit light-mode wait lucid atload"!_zsh_autosuggest_start" \
|
|
for @zsh-users/zsh-autosuggestions
|
|
|
|
# Map ctrl+x h to show completion context info.
|
|
bindkey '^Xh' _complete_help
|
|
|
|
# Group completions by type under group headings
|
|
zstyle ':completion:*' format '%B[%d]%b'
|
|
zstyle ':completion:*:descriptions' format '[%d]'
|
|
zstyle ':completion:*' group-name ''
|
|
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
|
|
zstyle ':completion:*' list-grouped true
|
|
zstyle ':autocomplete:*' groups 'always'
|
|
|
|
# Case-insensitive completion.
|
|
zstyle ':completion:*' matcher-list 'm:{[:lower:][:upper:]-_}={[:upper:][:lower:]_-}' 'r:|=*' 'l:|=* r:|=*'
|
|
|
|
# git
|
|
zstyle ':completion:*:*:git:*:branches' group-name 'local branches'
|
|
zstyle ':completion:*:*:git:*:remote-branches' group-name 'remote branches'
|
|
zstyle ':completion:*:*:git:*:tags' group-name 'tags'
|
|
zstyle ':completion:*:git-checkout:*' sort false
|
|
|
|
# Improve selection of Makefile completions - from:
|
|
# https://github.com/zsh-users/zsh-completions/issues/541#issuecomment-384223016
|
|
zstyle ':completion:*:make:*' tag-order targets
|
|
zstyle ':completion:*:make:*:targets' call-command true
|
|
|
|
autoload -Uz compinit
|
|
compinit
|
|
|
|
# Setup fzf related stuff if it is available.
|
|
if command-exists fzf; then
|
|
export FZF_DEFAULT_OPTS="
|
|
--bind=ctrl-k:kill-line
|
|
--bind=ctrl-v:half-page-down
|
|
--bind=alt-v:half-page-up
|
|
--tabstop=4
|
|
--highlight-line"
|
|
|
|
export FZF_CTRL_T_OPTS="
|
|
--walker-skip .git,node_modules,target
|
|
--bind 'ctrl-/:change-preview-window(down|hidden|)'"
|
|
|
|
# TODO: replace pbcopy with something that's cross-platform.
|
|
export FZF_CTRL_R_OPTS="
|
|
--border=none
|
|
--preview 'echo {}' --preview-window up:3:hidden:wrap
|
|
--bind 'ctrl-/:toggle-preview'
|
|
--bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'"
|
|
|
|
export FZF_ALT_C_OPTS="
|
|
--walker-skip .git,node_modules,target
|
|
--preview 'tree -C {}'"
|
|
|
|
export FZF_TMUX=0
|
|
export FZF_TMUX_HEIGHT="100%"
|
|
|
|
cached-eval "$(command -v fzf)" fzf --zsh
|
|
|
|
zstyle ':completion:*' menu no
|
|
zstyle ':completion:*' special-dirs true
|
|
|
|
zstyle ':fzf-tab:*' fzf-bindings 'ctrl-v:half-page-down' 'alt-v:half-page-up'
|
|
zstyle ':fzf-tab:*' fzf-flags '--highlight-line' '--tabstop=4'
|
|
zstyle ':fzf-tab:*' switch-group '<' '>'
|
|
|
|
# Use fzf-tab's tmux popup for tab completion.
|
|
zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup
|
|
zstyle ':fzf-tab:*' popup-min-size 80 10
|
|
zstyle ':fzf-tab:*' popup-pad 0 0
|
|
|
|
if command-exists eza; then
|
|
fzf_dir_preview='eza -1 --color=always --icons $realpath'
|
|
zstyle ':fzf-tab:complete:eza:*' fzf-preview "$fzf_dir_preview"
|
|
else
|
|
fzf_dir_preview='ls -1 --color=always $realpath'
|
|
fi
|
|
zstyle ':fzf-tab:complete:cd:*' fzf-preview "$fzf_dir_preview"
|
|
zstyle ':fzf-tab:complete:ls:*' fzf-preview "$fzf_dir_preview"
|
|
|
|
if command-exists bat; then
|
|
fzf_bat_preview='bat --color=always -n -r :500'
|
|
FZF_CTRL_T_OPTS="$FZF_CTRL_T_OPTS --preview '$fzf_bat_preview {}'"
|
|
zstyle ':fzf-tab:complete:bat:*' fzf-preview "$fzf_bat_preview \$realpath"
|
|
zstyle ':fzf-tab:complete:cat:*' fzf-preview "$fzf_bat_preview \$realpath"
|
|
else
|
|
FZF_CTRL_T_OPTS="$FZF_CTRL_T_OPTS --preview 'less {}'"
|
|
fi
|
|
fi
|
|
|
|
# ==============================================================================
|
|
# Visuals
|
|
# ==============================================================================
|
|
|
|
zinit light-mode wait lucid \
|
|
atinit"ZINIT[COMPINIT_OPTS]=-C; zicompinit; zicdreplay" \
|
|
for @zdharma-continuum/fast-syntax-highlighting
|
|
|
|
# ==============================================================================
|
|
# Edit command line
|
|
# ==============================================================================
|
|
|
|
autoload -z edit-command-line
|
|
zle -N edit-command-line
|
|
bindkey "^X^E" edit-command-line
|
|
|
|
# ==============================================================================
|
|
# Helper Functions
|
|
# ==============================================================================
|
|
|
|
source "$DOTZSH/zshrc.funcs.zsh"
|
|
|
|
# ==============================================================================
|
|
# Private Dotfiles
|
|
# ==============================================================================
|
|
|
|
if [ -f "$DOTPFILES/zshrc" ]; then
|
|
source "$DOTPFILES/zshrc"
|
|
fi
|
|
|
|
# ==============================================================================
|
|
# Environment and Tool Managers
|
|
# ==============================================================================
|
|
|
|
# If available, make sure to load direnv shell hook before mise.
|
|
if command-exists direnv; then
|
|
cached-eval "$(command -v direnv)" direnv hook zsh
|
|
fi
|
|
|
|
MISE_HOME="$HOME/.local/share/mise"
|
|
MISE_ZSH_INIT="$MISE_HOME/shell/init.zsh"
|
|
export MISE_INSTALL_PATH="$MISE_HOME/bin/mise"
|
|
|
|
if ! command-exists mise; then
|
|
read -q 'REPLY?mise is not installed, install with `curl https://mise.run | sh`? [y/N]:' &&
|
|
echo && curl https://mise.run | sh
|
|
fi
|
|
|
|
if command-exists mise; then
|
|
alias mi="mise"
|
|
|
|
setup-completions mise "$MISE_INSTALL_PATH" mise completions zsh
|
|
cached-eval "$MISE_INSTALL_PATH" mise activate zsh
|
|
fi
|
|
|
|
# ==============================================================================
|
|
# Prompt
|
|
# ==============================================================================
|
|
|
|
if ! command-exists starship && [ -f "$MISE_INSTALL_PATH" ]; then
|
|
read -q 'REPLY?starship is not installed, install with `mise install starship`? [y/N]:' &&
|
|
echo && "$MISE_INSTALL_PATH" install starship
|
|
fi
|
|
|
|
if command-exists starship; then
|
|
setup-completions starship "$(command -v starship)" starship completions zsh
|
|
cached-eval "$(command -v starship)" starship init zsh --print-full-init
|
|
else
|
|
echo "WARN: starship not found, skipping prompt setup" >&2
|
|
echo " install with: mise install starship" >&2
|
|
|
|
fi
|
|
|
|
# ==============================================================================
|
|
# Tool specific setup
|
|
# ==============================================================================
|
|
|
|
# Aliases
|
|
source "$DOTZSH/aliases.zsh"
|
|
|
|
# OS specific
|
|
if [[ "$OSTYPE" == "darwin"* ]]; then source "$DOTZSH/macos.zsh"; fi
|
|
if [[ "$OSTYPE" == "linux"* ]]; then source "$DOTZSH/linux.zsh"; fi
|
|
|
|
# Utils
|
|
source "$DOTZSH/1password.zsh"
|
|
source "$DOTZSH/copilot.zsh"
|
|
source "$DOTZSH/emacs.zsh"
|
|
source "$DOTZSH/less.zsh"
|
|
source "$DOTZSH/mise.zsh"
|
|
source "$DOTZSH/neovim.zsh"
|
|
source "$DOTZSH/nix.zsh"
|
|
source "$DOTZSH/tldr.zsh"
|
|
source "$DOTZSH/tmux.zsh"
|
|
source "$DOTZSH/zoxide.zsh"
|
|
|
|
# Development
|
|
source "$DOTZSH/containers.zsh"
|
|
source "$DOTZSH/git.zsh"
|
|
source "$DOTZSH/golang.zsh"
|
|
source "$DOTZSH/google-cloud.zsh"
|
|
source "$DOTZSH/kubernetes.zsh"
|
|
source "$DOTZSH/nodejs.zsh"
|
|
source "$DOTZSH/python.zsh"
|
|
source "$DOTZSH/ruby.zsh"
|
|
source "$DOTZSH/rust.zsh"
|
|
source "$DOTZSH/scaleway.zsh"
|
|
|
|
# ==============================================================================
|
|
# Basic Z-Shell settings
|
|
# ==============================================================================
|
|
|
|
# Disable auto-title.
|
|
DISABLE_AUTO_TITLE="true"
|
|
|
|
# Disable shared history.
|
|
unsetopt share_history
|
|
|
|
# Disable attempted correction of commands (is wrong 98% of the time).
|
|
unsetopt correctall
|
|
|
|
# ==============================================================================
|
|
# Local Overrides
|
|
# ==============================================================================
|
|
|
|
if [ -f "$HOME/.zshrc.local" ]; then
|
|
source "$HOME/.zshrc.local"
|
|
fi
|
|
|
|
autoload -U +X bashcompinit && bashcompinit
|