dotfiles/terminal/.config/zsh/zshrc
Marty Oehme acc2496bd6
terminal: Move bash and zsh into config directory
With the power of dotter for dotfile management we can move the files we
want to link anywhere in our repository.

So finally we're making use of it to keep the bash config files in the
`terminal/.config/bash` directory, as well as removing the leading dot
from both the zsh configuration files.
2025-10-13 11:26:22 +02:00

280 lines
10 KiB
Bash

#!/usr/bin/env zsh
CONFDIR="${XDG_CONFIG_HOME:-$HOME/.config}"
ZSHCONFDIR="$CONFDIR/zsh"
# load completion, extended zsh moving syntax, zle edit in vim (or other $EDITOR) possibility
autoload -Uz compinit zmv edit-command-line run-help run-help-git run-help-ip run-help-sudo
# Set completion style
# The following lines were added by compinstall
zstyle ':completion:*' completer _complete _ignored _approximate
zstyle ':completion:*' matcher-list '' '+m:{[:lower:]}={[:upper:]} r:|[._-]=** r:|=**'
zstyle ':completion:*' menu select=1
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle :compinstall filename "$ZSHCONFDIR/.zshrc"
compinit
# End of lines added by compinstall
# load plugins with the zr plugin manager
AUTO_NOTIFY_THRESHOLD=60
TIPZ_TEXT='ALIAS:'
if command -v zr >/dev/null 2>&1; then
. <(
zr \
molovo/tipz \
ael-code/zsh-colored-man-pages \
MichaelAquilina/zsh-auto-notify \
Aloxaf/fzf-tab \
zdharma-continuum/fast-syntax-highlighting \
zsh-users/zsh-autosuggestions \
zsh-users/zsh-completions \
)
else # or manually
[ -e /usr/share/oh-my-zsh/plugins/colored-man-pages/colored-man-pages.plugin.zsh ] && source /usr/share/oh-my-zsh/plugins/colored-man-pages/colored-man-pages.plugin.zsh
[ -e /usr/share/oh-my-zsh/plugins/command-not-found/command-not-found.plugin.zsh ] && source /usr/share/oh-my-zsh/plugins/command-not-found/command-not-found.plugin.zsh
## find the correct installed tab-completion version
PLUG_FOLDER="/usr/share/zsh/plugins"
[ -e $PLUG_FOLDER/fzf-tab/fzf-tab.plugin.zsh ] && source $PLUG_FOLDER/fzf-tab/fzf-tab.plugin.zsh
[ -e $PLUG_FOLDER/fzf-tab-bin-git/fzf-tab.plugin.zsh ] && source $PLUG_FOLDER/fzf-tab-bin-git/fzf-tab.plugin.zsh
# these need to be sourced after fzf-tab
[ -e $PLUG_FOLDER/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh ] && source $PLUG_FOLDER/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
[ -e $PLUG_FOLDER/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ] && source $PLUG_FOLDER/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
[ -e $PLUG_FOLDER/alias-tips/alias-tips.plugin.zsh ] && source $PLUG_FOLDER/alias-tips/alias-tips.plugin.zsh
[ -e $PLUG_FOLDER/zsh-autosuggestions/zsh-autosuggestions.plugin.zsh ] && source $PLUG_FOLDER/zsh-autosuggestions/zsh-autosuggestions.plugin.zsh
fi
unset PLUG_FOLDER
# simple fzf-tab settings
zstyle ":fzf-tab:*" fzf-flags "--ansi" "--expect='$continuous_trigger,$print_query'" "--color=hl:$(($#headers == 0 ? 108 : 255))" "--nth=2,3" "--layout=reverse" "--height=${FZF_TMUX_HEIGHT:-75%}" "--tiebreak=begin" "-m" "--bind=tab:down,btab:up,change:top,ctrl-space:toggle" "--cycle" "--query=$query" "--header-lines=$#headers" "--print-query"
# enable inserting files or dirs using fzf with ctrl-t
FZF_CTRL_R_COMMAND="" FZF_ALT_C_COMMAND="" source <(fzf --zsh)
zstyle ':fzf-tab:*' fzf-command fzf
# format colorful groups for different completion actions
zstyle ':completion:*:descriptions' format '[%d]'
# set list-colors to enable filename colorizing
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
# force zsh not to show completion menu, which allows fzf-tab to capture the unambiguous prefix
zstyle ':completion:*' menu no
# fzf-tab does not follow FZF_DEFAULT_OPTS by default since some setups can break completion
zstyle ':fzf-tab:*' fzf-flags --color=fg:1,fg+:2
zstyle ':fzf-tab:*' fzf-bindings 'ctrl-j:accept' 'ctrl-a:toggle-all' 'ctrl-d:preview-down' 'ctrl-u:preview-up'
zstyle ':fzf-tab:*' continuous-trigger '/'
zstyle ':fzf-tab:*' switch-group '<' '>'
# use input as query string when completing zlua
zstyle ':fzf-tab:complete:_zlua:*' query-string input
# (experimental, may change in the future)
# some boilerplate code to define the variable `extract` which will be used later
# please remember to copy them
local extract="
# trim input(what you select)
local in=\${\${\"\$(<{f})\"%\$'\0'*}#*\$'\0'}
# get ctxt for current completion(some thing before or after the current word)
local -A ctxt=(\"\${(@ps:\2:)CTXT}\")
# real path
local realpath=\${ctxt[IPREFIX]}\${ctxt[hpre]}\$in
realpath=\${(Qe)~realpath}
"
# give a preview of commandline arguments when completing `kill`
zstyle ':completion:*:*:*:*:processes' command "ps -u $USER -o pid,user,comm -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:(kill|ps):argument-rest' fzf-flags --preview-window=down:3:wrap
# preview directory's content with eza when completing cd
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath'
# show systemd unit status
zstyle ':fzf-tab:complete:systemctl-*:*' fzf-preview 'SYSTEMD_COLORS=1 systemctl status $word'
# env var contents
zstyle ':fzf-tab:complete:(-command-|-parameter-|-brace-parameter-|export|unset|expand):*' \
fzf-preview 'echo ${(P)word}'
# show hostname if we are in a distrobox environment
if [ -n "$DISTROBOX_ENTER_PATH" ] && [ -f /run/.containerenv ]; then
local container=lxc
fi
# shellcheck source=alias
[ -f "$CONFDIR/sh/alias" ] && source "$CONFDIR/sh/alias"
# load additional aliases
if [ -d "$CONFDIR/sh/alias.d" ]; then
for _alias in "$CONFDIR/sh/alias.d"/*.sh; do
source "$_alias"
done
unset _alias
fi
# shellcheck source=alias
[ -f "$ZSHCONFDIR/alias" ] && source "$ZSHCONFDIR/alias"
if [ -d "$ZSHCONFDIR/alias.d" ]; then
for _alias in "$ZSHCONFDIR/alias.d"/*.zsh; do
source "$_alias"
done
unset _alias
fi
# Correct spelling for commands
setopt correct
# turn off the infernal correctall for filenames
unsetopt correctall
# Enable command auto-correction.
ENABLE_CORRECTION="true"
# allow moving through directories without prepending cd
setopt autocd
eval "$(starship init zsh)"
eval "$(zoxide init zsh)"
eval "$(atuin init zsh)"
export CARAPACE_BRIDGES='zsh,fish,bash,inshellisense' # optional
source <(carapace _carapace)
# make fzf-tab compatible with carapace
# see <https://github.com/carapace-sh/carapace-bin/issues/2819#issuecomment-3092307945>
zstyle ':fzf-tab:*' query-string ''
# Speed up autocomplete, force prefix mapping
zstyle ':completion:*' accept-exact '*(N)'
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path "${XDG_CACHE_HOME:-$HOME/.cache}/zshcompcache"
### history
## Set ZSH History defaults
setopt append_history
setopt extended_history # record command start time
setopt hist_ignore_dups
setopt hist_ignore_all_dups # do not put duplicated command into history list
setopt hist_save_no_dups # do not save duplicated command
setopt hist_expire_dups_first
setopt hist_ignore_space
setopt hist_reduce_blanks # remove unnecessary blanks
setopt hist_verify
setopt inc_append_history_time # append command to history file immediately after execution
setopt share_history # Share your history across all your terminal windows
setopt pushd_ignore_dups
#setopt pushd_silent
export HISTSIZE=1000000
export SAVEHIST=1000000
export HISTFILE="$XDG_DATA_HOME/zsh_history"
export HISTORY_IGNORE="(jrnl *|l *|ls *|z *|cd *|cd -|pwd|pwd *|exit|date)"
## Set ZSH History aliases
# Show the top 5 commands used in recent history
history_top() {
history | awk "{a[\$2]++} END{for(i in a){printf \"%5d\t%s\n\",a[i],i}}" | sort -rn | head
}
# Display timestamped recent command history
alias history="fc -l -d -D"
### Glob Alias expansion
# Expand aliases inline - see http://blog.patshead.com/2012/11/automatically-expaning-zsh-global-aliases---simplified.html
globalias() {
if [[ $LBUFFER =~ [A-Z0-9]+$ ]]; then
zle _expand_alias
zle expand-word
fi
zle self-insert
}
zle -N globalias
bindkey " " globalias
bindkey "^ " magic-space # control-space to bypass completion
bindkey -M isearch " " magic-space # normal space during searches
# allow inserting previous arguments in the current zle input
# see https://stackoverflow.com/a/34861762
bindkey "^[." insert-last-word
# VIM MODE for the shell
# enable vim mode on pressing escape
bindkey -v
# remove the delay for switching modes
export KEYTIMEOUT=1
# Change cursor shape for different vi modes.
function zle-keymap-select {
if [[ ${KEYMAP} == vicmd ]] ||
[[ $1 = 'block' ]]; then
echo -ne '\e[2 q'
elif [[ ${KEYMAP} == main ]] ||
[[ ${KEYMAP} == viins ]] ||
[[ ${KEYMAP} = '' ]] ||
[[ $1 = 'beam' ]]; then
echo -ne '\e[6 q'
fi
}
zle -N zle-keymap-select
# Use beam shape cursor on startup.
_fix_cursor() {
echo -ne '\e[6 q'
}
precmd_functions+=(_fix_cursor)
_run-cdi() {
local dir="$(eval "zoxide query -i")"
if [[ -z "$dir" ]]; then
zle redisplay
return 0
fi
zle push-line
BUFFER="builtin cd -- ${(q)dir}"
zle accept-line
local ret=$?
unset dir
zle reset-prompt
return $ret
}
zle -N _run-cdi
# use alt-c or C in cmd mode to change dir using zoxide
bindkey '\ec' _run-cdi
bindkey -M vicmd 'C' _run-cdi
# add file insertion with fzf to T in cmd mode (c-t in insert)
# insert-mode keybind is above, using regular fzf sourcing
bindkey -M vicmd 'T' fzf-file-widget
# space puts a space, even in cmd mode
bindkey -a ' ' magic-space
# always allow backspace/delete to remove letters
bindkey '^?' backward-delete-char
bindkey -a '^?' backward-delete-char
bindkey '^h' backward-delete-char
bindkey -a '^h' backward-delete-char
# and forward with delete
bindkey '^[[3~' delete-char
bindkey -a '^[[3~' delete-char
# always allow removing words with <c-w>
bindkey -a '^w' backward-kill-word
# enable cycling through previous commands with <c-p/n>
bindkey '^P' history-beginning-search-backward
bindkey '^N' history-beginning-search-forward
# search history backwards <c-r>
bindkey '^o' history-incremental-search-backward
bindkey -M vicmd '^o' history-incremental-search-backward
bindkey '^r' atuin-search-viins
bindkey -M vicmd '^r' atuin-search-vicmd
# cycle through history results
bindkey -M isearch '^P' history-incremental-search-backward
bindkey -M isearch '^N' history-incremental-search-forward
# Send command to editor and back for execution
zle -N edit-command-line
bindkey '^e' edit-command-line
bindkey -M vicmd '^e' edit-command-line
# give manpage when hitting K from vi mode
bindkey -M vicmd 'K' run-help run-help-git run-help-ip run-help-sudo run-help
# Deduplicate PATH - remove any duplicate entries from PATH
# from: https://unix.stackexchange.com/questions/40749/remove-duplicate-path-entries-with-awk-command
get_var() {
eval 'printf "%s\n" "${'"$1"'}"'
}
set_var() {
eval "$1=\"\$2\""
}
unset CONFDIR
unset ZSHCONFDIR