dotfiles/zshrc

500 lines
13 KiB
Bash
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

autoload -U colors && colors
# Set the ZSH cache directory and make sure that it exists
ZSH_CACHE_DIR="$HOME/.cache/zsh"
if [ ! -d "$ZSH_CACHE_DIR" ]; then
mkdir -p "$ZSH_CACHE_DIR"
fi
# Load all the stock functions
autoload -U compaudit compinit zercompile
compinit -u
zmodload -i zsh/complist
WORDCHARS=''
unsetopt menu_complete # do not autoselect the first completion entry
unsetopt flowcontrol
setopt auto_cd
setopt auto_menu # show completion menu on successive tab press
setopt auto_pushd
setopt always_to_end
setopt complete_in_word
setopt long_list_jobs
setopt pushd_ignore_dups
setopt pushdminus
setopt interactivecomments
stty stop undef
unsetopt beep
bindkey -M menuselect '^o' accept-and-infer-next-history
zstyle ':completion:*:*:*:*:*' menu select
zstyle ':completion:*' matcher-list 'm:{[:lower:][:upper:]-_}={[:upper:][:lower:]_-}' 'r:|=*' 'l:|=* r:|=*'
# Complete . and .. special directories
zstyle ':completion:*' special-dirs true
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01'
zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm -w -w"
# disable sort when completing `git checkout`
zstyle ':completion:*:git-checkout:*' sort false
# set descriptions format to enable group support
# NOTE: don't use escape sequences here, fzf-tab will ignore them
zstyle ':completion:*:descriptions' format '[%d]'
# set list-colors to enable filename colorizing
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
# disable named-directories autocompletion
zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories
# Preview directory's content with eza when completing cd
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath'
# switch group using `<` and `>`
zstyle ':fzf-tab:*' switch-group '<' '>'
# Use tmux (v3.2+) popup feature
# zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup
autoload -U +X bashcompinit && bashcompinit
[ "$HISTSIZE" -lt 50000 ] && HISTSIZE=50000
[ "$SAVEHIST" -lt 10000 ] && SAVEHIST=10000
setopt extended_history # record timestamp of command in HISTFILE
setopt hist_expire_dups_first # delete duplicates first when HISTFILE size exceeds HISTSIZE
setopt hist_ignore_dups # ignore duplicated commands history list
setopt hist_ignore_space # ignore commands that start with space
setopt hist_verify # show command with history expansion to user before running it
setopt share_history # share command history data
bindkey -e
# [PageUp] - Up a line of history
if [[ -n "${terminfo[kpp]}" ]]; then
bindkey -M emacs "${terminfo[kpp]}" up-line-or-history
fi
# [PageDown] - Down a line of history
if [[ -n "${terminfo[knp]}" ]]; then
bindkey -M emacs "${terminfo[kpp]}" up-line-or-history
fi
# Start typing + [Up-Arrow] - fuzzy find history forward
if [[ -n "${terminfo[kcuu1]}" ]]; then
autoload -U up-line-or-beginning-search
zle -N up-line-or-beginning-search
bindkey -M emacs "${terminfo[kcuu1]}" up-line-or-beginning-search
fi
# Start typing + [Down-Arrow] - fuzzy find history backward
if [[ -n "${terminfo[kcud1]}" ]]; then
autoload -U down-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey -M emacs "${terminfo[kcud1]}" down-line-or-beginning-search
fi
# [Home] - Go to beginning of line
if [[ -n "${terminfo[khome]}" ]]; then
bindkey -M emacs "${terminfo[khome]}" beginning-of-line
fi
# [End] - Go to end of line
if [[ -n "${terminfo[kend]}" ]]; then
bindkey -M emacs "${terminfo[kend]}" end-of-line
fi
# [Backspace] - delete backward
bindkey -M emacs '^?' backward-delete-char
# [Delete] - delete forward
if [[ -n "${terminfo[kdch1]}" ]]; then
bindkey -M emacs "${terminfo[kdch1]}" delete-char
else
bindkey -M emacs "^[[3~" delete-char
bindkey -M emacs "^[3;5~" delete-char
fi
# [Ctrl-Delete] - delete whole forward-word
bindkey -M emacs '^[[3;5~' kill-word
# [Ctrl-RightArrow] - move forward one word
bindkey -M emacs '^[[1;5C' forward-word
# [Ctrl-LeftArrow] - move backward one word
bindkey -M emacs '^[[1;5D' backward-word
# Edit the current command line in $EDITOR
autoload -U edit-command-line
zle -N edit-command-line
bindkey '\C-x\C-e' edit-command-line
bindkey '^W' kill-region
bindkey '^I' complete-word
function _log_note() {
echo -e "\e[1m\e[36mNOTE:\e[0m" "$@"
}
function _log_warn() {
echo -e "\e[1m\e[1;33mWARN:\e[0m" "$@"
}
if [[ ! -d "$HOME/.local/share/zsh" ]]; then
_log_note "Creating '$HOME/.local/share/zsh' directory"
mkdir -p "$HOME/.local/share/zsh"
fi
if [[ ! -d "$HOME/.local/share/zsh/fzf-tab" ]]; then
if command -v git >/dev/null; then
_log_note "Cloning fzf-tab into '$HOME/.local/share/zsh/fzf-tab'"
git clone --depth 1 https://github.com/Aloxaf/fzf-tab "$HOME/.local/share/zsh/fzf-tab"
else
_log_warn "No 'git' command available; unable to clone fzf-tab"
fi
fi
if [[ -d "$HOME/.local/share/zsh/fzf-tab" ]]; then
source "$HOME/.local/share/zsh/fzf-tab/fzf-tab.plugin.zsh"
else
_log_warn "fzf-tab not available"
fi
function greeting() {
# if command -v neofetch >/dev/null; then
# neofetch
# fi
function _format {
awk -F ';' '{ printf(" \x1b[37m%-30s \x1b[96m%s\x1b[0m\n", $1, $2) }'
}
function format {
echo "$1:;$2" | _format
}
format "Hostname" "$(hostname -s)"
format "Uptime" "$(uptime | sed 's/.*up \([^,]*\),.*/\1/')"
format "System Load" "$(uptime | sed 's/.*load av.*: \(.*\)/\1/')"
format "Running Processes" "$(ps -caxm | tail -n +2 | wc -l | awk '{ print $1 }')"
format "Resident Set Size" "$(ps aux | awk '{ sum += $6 } END { printf("%.2f MiB", sum / 1024.0) }')"
local ifconfig_script='
/^[a-zA-Z0-9]+:/ {
iface = substr($1, 0, length($1) - 1)
}
/^[ \t]+inet / {
printf("IPv4 Address for %s:;%s\n", iface, $2)
}
'
ifconfig | awk "$ifconfig_script" | while read inet_line; do
echo $inet_line | _format
done
echo # blank line
}
function clear_screen() {
clear
greeting
if [ -d /var/mail/blake ] && mail -e; then
echo "You have mail"
fi
}
alias cls=clear_screen
if [ "$(uname)" = "Darwin" ]; then
function _clipboard_copy() {
pbcopy
}
else
function _clipboard_copy() {
xclip -selection clipboard
}
fi
function copydir() {
pwd | tr -d "\r\n" | _clipboard_copy
}
function copyfile() {
[[ "$#" != 1 ]] && return 1
local file_to_copy=$1
cat $file_to_copy | _clipboard_copy
}
function copybuffer() {
local buf=""
if test -z $BUFFER; then
buf=$(fc -ln -1)
else
buf=$BUFFER
fi
printf "%s" "$buf" | _clipboard_copy
}
zle -N copybuffer
bindkey '^O' copybuffer
function google() {
if [[ $# -lt 1 ]]; then
open "https://www.google.co.uk/"
return
fi
url="https://www.google.co.uk/search?q="
while [[ $# -gt 0 ]]; do
url="${url}$1+"
shift
done
url="${url%?}"
open "$url"
}
# If we have a `~/.local/bin` directory, then add it to the path
if [[ -d $HOME/.local/bin ]]; then
export PATH="$HOME/.local/bin:$PATH"
fi
if [[ -d $HOME/.cargo/bin ]]; then
export PATH="$HOME/.cargo/bin:$PATH"
else
_log_warn "No Rust Cargo bin directory found"
fi
# Add the GitHub CLI if it exists
if command -v gh >/dev/null; then
eval "$(gh completion -s zsh)"
else
_log_warn "No GitHub CLI found"
fi
alias gg="nvim +:NeogitStart"
# Add aliases to relace 'ls' (and similar) to 'exa'
if command -v eza >/dev/null; then
alias exa=eza
alias l=eza
alias ls=eza
alias ll="eza -l --git --icons"
alias lll="eza -la --git --icons"
alias lt="eza --tree --git --icons"
elif command -v exa >/dev/null; then
alias l=exa
alias ls=exa
alias ll="exa -l --git --icons"
alias lll="exa -la --git --icons"
alias lt="exa --tree --git --icons"
else
alias l=ls
alias ll="ls -l"
alias lll="ls -la"
if command -v tree >/dev/null; then
alias lt="tree"
else
alias lt="echo 'Need to install eza'"
fi
fi
# Use `dust` instead of `du`
if command -v dust >/dev/null; then
alias du=dust
alias duu=du
fi
# Use 'duf' stead of 'df'
if command -v duf >/dev/null; then
alias df=duf
fi
# See if `xplr` is knocking around
if command -v xplr >/dev/null; then
alias x=xplr
# Change to a directory selected with `xplr`
alias xcd='cd "$(xplr --print-pwd-as-result)"'
# Edit a file selected with `xplr` using `nvim`
alias xnvim='nvim "$(xplr)"'
alias xv='xnvim'
else
_log_note "Need to install xplr; xplr will not be available"
alias x=ls
fi
if command -v ranger >/dev/null; then
alias r=ranger
fi
if command -v nvim >/dev/null; then
alias v=nvim
else
_log_warn "No Neovim found"
fi
if command -v fzf >/dev/null; then
alias f="fzf --height 40 --layout=reverse --border --preview 'bat --style=numbers --color=always {}'"
alias fv="fzf --height 40 --layout=reverse --border --preview 'bat --style=numbers --color=always {}' | xargs nvim"
else
_log_note "Need to install fzf; visit https://github.com/junegunn/fzf"
fi
if command -v ag >/dev/null; then
export FZF_DEFAULT_COMMAND='ag --hidden --ignore .git -l -g ""'
else
_log_note "Need to install ag; visit https://github.com/ggreer/the_silver_searcher"
fi
if command -v rg >/dev/null; then
function rgv() {
rg -n "$@" | fzf --height 40 --layout=reverse --border --preview "$HOME/cs/dotfiles/zsh/_rgv_preview.sh"' {}' | cut -d':' -f1,2 | xargs -n 1 "$HOME/cs/dotfiles/zsh/_rgv_edit.sh"
}
else
_log_note "Need to install rg; visit https://github.com/BurntSushi/ripgrep"
fi
if [[ -f $HOME/.opam/opam-init/init.zsh ]]; then
source $HOME/.opam/opam-init/init.zsh > /dev/null 2> /dev/null
fi
# FZF auto-completion and key bindings
if [ -d /opt/homebrew/opt/fzf/shell ]; then
source "/opt/homebrew/opt/fzf/shell/completion.zsh" 2> /dev/null
source "/opt/homebrew/opt/fzf/shell/key-bindings.zsh"
elif [ -d /usr/share/fzf ]; then
source "/usr/share/fzf/completion.zsh" 2> /dev/null
source "/usr/share/fzf/key-bindings.zsh"
elif [ -d /usr/share/doc/fzf/examples ]; then
source "/usr/share/doc/fzf/examples/completion.zsh" 2> /dev/null
source "/usr/share/doc/fzf/examples/key-bindings.zsh"
else
_log_warn "Missing zsh fzf completion and key-bindings"
fi
export EDITOR=nvim
export PAGER=less
export LESS=-R
if command -v jq >/dev/null; then
if [ -f ~/.openai.secret-key.json ]; then
export OPENAI_API_KEY=$(cat "$HOME/.openai.secret-key.json" | jq -r ".secretKey")
else
_log_warn "OpenAI secret key not found; OPENAI_API_KEY will not be available"
fi
else
_log_warn "Need to install jq; OPENAI_API_KEY will not be available"
fi
greeting
if command -v oh-my-posh >/dev/null; then
if [ "$TERM_PROGRAM" != "Apple_Terminal" ]; then
eval "$(oh-my-posh init zsh --config $HOME/.config/ohmyposh/zen.toml)"
else
_log_warn "oh-my-posh not available in Apple Terminal"
fi
else
_log_warn "Need to install oh-my-posh: https://ohmyposh.dev/"
fi
function load_dotfile() {
if [ -f $HOME/cs/dotfiles/zsh/$1.zsh ]; then
source $HOME/cs/dotfiles/zsh/$1.zsh
elif [ -f $HOME/.config/zsh/$1.zsh ]; then
source $HOME/.config/zsh/$1.zsh
else
_log_warn "Unable to find '$1.zsh' (in Synology dotfiles or ~/.config/zsh)"
fi
}
function load_share() {
if [ -f /opt/homebrew/share/$1/$1.zsh ]; then
source /opt/homebrew/share/$1/$1.zsh
elif [ -f /usr/share/$1/$1.zsh ]; then
source /usr/share/$1/$1.zsh
elif [ -f /usr/share/zsh/plugins/$1/$1.zsh ]; then
source /usr/share/zsh/plugins/$1/$1.zsh
else
_log_warn "Unable to find '$1' (in Homebrew or /usr/share)"
fi
}
load_dotfile "1password"
load_dotfile "p10k"
load_dotfile "dir-history"
load_dotfile "dir-persist"
load_dotfile "misc"
load_dotfile "completions/eksctl"
if [ "$(uname)" = "Darwin" ]; then
load_dotfile "osx"
fi
load_share "zsh-autosuggestions"
load_share "zsh-syntax-highlighting"
if command -v atuin >/dev/null; then
eval "$(atuin init zsh)"
else
_log_note "Need to install atuin; visit https://atuin.sh/docs/ and follow QuickStart"
_log_note "(Authentication credentials are in password manager)"
fi
if command -v zoxide >/dev/null; then
eval "$(zoxide init --cmd cd zsh)"
else
_log_note "Need to install zoxide; visit https://github.com/ajeetdsouza/zoxide"
fi
if [[ -f "$HOME/.ghcup/env" ]]; then
source "$HOME/.ghcup/env"
else
_log_note "Note: ghcup not installed (or no ~/.ghcup directory)"
fi
# See https://github.com/nvm-sh/nvm#installation-and-update
if [[ -z "$NVM_DIR" ]]; then
if [[ -d "$HOME/.nvm" ]]; then
export NVM_DIR="$HOME/.nvm"
elif [[ -d "${XDG_CONFIG_HOME:-$HOME/.config}/nvm" ]]; then
export NVM_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/nvm"
elif (( $+commands[brew] )); then
NVM_HOMEBREW="${NVM_HOMEBREW:-${HOMEBREW_PREFIX:-$(brew --prefix)}/opt/nvm}"
if [[ -d "$NVM_HOMEBREW" ]]; then
export NVM_DIR="$NVM_HOMEBREW"
fi
else
_log_note "Note: nvm not installed (or no ~/.nvm directory)"
fi
fi
if [[ -f "$NVM_DIR/nvm.sh" ]]; then
source "$NVM_DIR/nvm.sh"
fi
if [[ -f "$NVIM_DIR/bash_completion" ]]; then
source "$NVIM_DIR/bash_completion"
fi
if command -v kubctl >/dev/null; then
source <(kubectl completion zsh)
fi
export LEDGER_FILE="$HOME/cs/hledger/main.journal"
PATH="/Users/blakerain/perl5/bin${PATH:+:${PATH}}"; export PATH;
PERL5LIB="/Users/blakerain/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/Users/blakerain/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/Users/blakerain/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/Users/blakerain/perl5"; export PERL_MM_OPT;