aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/home
diff options
context:
space:
mode:
authorLibravatar sommerfeld <[email protected]>2026-04-17 10:53:27 +0100
committerLibravatar sommerfeld <[email protected]>2026-04-17 10:53:27 +0100
commitbf32d51f8e780dfb52fbbd080eef5e110232f065 (patch)
treec466166c4aa0480484e2561084e22725b31a0caf /home
parent46dcad8576553c3387b950cbf5eebd3b06cd17b3 (diff)
downloaddotfiles-bf32d51f8e780dfb52fbbd080eef5e110232f065.tar.gz
dotfiles-bf32d51f8e780dfb52fbbd080eef5e110232f065.tar.bz2
dotfiles-bf32d51f8e780dfb52fbbd080eef5e110232f065.zip
refactor: rewrite .zshrc as unified interactive config
Merge aliases into .zshrc and fix multiple bugs: - Fix: remove duplicate zle application mode block (lines 110-115) - Fix: select-word-style called once (shell), was called twice (bash then shell) - Fix: remove contradictory no_complete_aliases/COMPLETE_ALIASES setopts - Fix: remove 'set zle_bracketed_paste' (wrong syntax, did nothing) - Remove: case $- guard (unnecessary — zsh only sources .zshrc interactively) - Remove: shinit sourcing (replaced by direct config in .zprofile/.zshrc) - Remove: safesource calls (direct source) - Remove: ZSH_AUTOSUGGEST_USE_ASYNC (deprecated, async is default) - Remove: run-help-sudo (system uses doas) - Remove: bash() wrapper function (no longer needed) - Remove: initial Up/Down bindings (immediately overridden by prefix search) - Organize into clearly labeled sections with comments - Consolidate compdef calls
Diffstat (limited to 'home')
-rw-r--r--home/.config/zsh/.zshrc305
1 files changed, 178 insertions, 127 deletions
diff --git a/home/.config/zsh/.zshrc b/home/.config/zsh/.zshrc
index 59d7fad..e75cde8 100644
--- a/home/.config/zsh/.zshrc
+++ b/home/.config/zsh/.zshrc
@@ -1,71 +1,56 @@
-case $- in
- *i*) stty -ixon
- ;;
- *) return
- ;;
-esac
+# Interactive zsh configuration.
-ttyctl -f
-# Enable colors and change prompt:
-autoload -U colors
+# ── Terminal ──────────────────────────────────────────────────────────────────
+stty -ixon # disable XON/XOFF flow control (frees Ctrl-S/Ctrl-Q)
+ttyctl -f # freeze terminal state; programs can't leave it broken
-# shellcheck source=/dev/null
-[ -r ~/.config/sh/shinit ] && . ~/.config/sh/shinit
+# ── Options ───────────────────────────────────────────────────────────────────
+setopt appendhistory # append to history file, don't overwrite
+setopt autocd # cd by typing directory name
+setopt extendedglob # extended glob patterns (#, ~, ^)
+setopt nomatch # error on unmatched glob patterns
+setopt notify # report background job status immediately
+setopt interactivecomments # allow # comments in interactive shell
+setopt rmstarsilent # don't confirm rm *
+setopt prompt_subst # expand variables/functions in prompt
+unsetopt beep # no terminal bell
-safesource /usr/share/git/completion/git-prompt.sh
-
-colors
-setopt PROMPT_SUBST
-PROMPT='%B%{$fg[green]%}%n%{$reset_color%}@%{$fg[cyan]%}%m%{$reset_color%}:%b%{$fg[yellow]%}%~%{$reset_color%}$(__git_ps1 " (%s)")%(?..[%{$fg[red]%}%?%{$reset_color%}]) %(!.#.>) '
-
-HISTFILE="$XDG_CACHE_HOME"/zsh_history
+# ── History ───────────────────────────────────────────────────────────────────
+HISTFILE="$XDG_CACHE_HOME/zsh_history"
HISTSIZE=50000
SAVEHIST=50000
-setopt appendhistory autocd extendedglob nomatch notify
-unsetopt beep
+
+# ── Emacs keybindings ─────────────────────────────────────────────────────────
bindkey -e
+# ── Prompt ────────────────────────────────────────────────────────────────────
+autoload -Uz colors && colors
+source /usr/share/git/completion/git-prompt.sh
+PROMPT='%B%{$fg[green]%}%n%{$reset_color%}@%{$fg[cyan]%}%m%{$reset_color%}:%b%{$fg[yellow]%}%~%{$reset_color%}$(__git_ps1 " (%s)")%(?..[%{$fg[red]%}%?%{$reset_color%}]) %(!.#.>) '
+
+# ── Completion ────────────────────────────────────────────────────────────────
fpath=($XDG_DATA_HOME/zsh/completion $fpath)
-autoload -Uz compinit
-compinit
+autoload -Uz compinit && compinit
+
zstyle ':completion:*' menu select
-zstyle ':completion::complete:*' gain-privileges 1
zstyle ':completion:*' completer _expand_alias _complete _ignored _match _approximate
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
-
zstyle ':completion:*' use-cache on
-zstyle ':completion:*' cache-path ~/.cache/zsh
-
+zstyle ':completion:*' cache-path "$XDG_CACHE_HOME/zsh"
zstyle ':completion:*:match:*' original only
-zstyle -e ':completion:*:approximate:*' \
- max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
-
zstyle ':completion:*:functions' ignored-patterns '_*'
-
zstyle ':completion:*:*:kill:*' menu yes select
-zstyle ':completion:*:kill:*' force-list always
+zstyle ':completion:*:kill:*' force-list always
zstyle ':completion:*:cd:*' ignore-parents parent pwd
-setopt no_complete_aliases
-
-rationalise-dot() {
- if [[ $LBUFFER = *.. ]]; then
- LBUFFER+=/..
- else
- LBUFFER+=.
- fi
-}
-zle -N rationalise-dot
-bindkey . rationalise-dot
-
-setopt COMPLETE_ALIASES
-_comp_options+=(globdots) # Include hidden files.
+zstyle ':completion::complete:*' gain-privileges 1
+zstyle -e ':completion:*:approximate:*' \
+ max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
-setopt rmstarsilent
+_comp_options+=(globdots) # include hidden files in completion
-# create a zkbd compatible hash;
-# to add other keys to this hash, see: man 5 terminfo
+# ── Terminal keys (zkbd-compatible) ───────────────────────────────────────────
+# Map terminfo keys so Home/End/Delete/etc. work in all terminals.
typeset -g -A key
-
key[Home]="${terminfo[khome]}"
key[End]="${terminfo[kend]}"
key[Insert]="${terminfo[kich1]}"
@@ -79,142 +64,208 @@ key[PageUp]="${terminfo[kpp]}"
key[PageDown]="${terminfo[knp]}"
key[ShiftTab]="${terminfo[kcbt]}"
-# setup key accordingly
[[ -n "${key[Home]}" ]] && bindkey -- "${key[Home]}" beginning-of-line
[[ -n "${key[End]}" ]] && bindkey -- "${key[End]}" end-of-line
[[ -n "${key[Insert]}" ]] && bindkey -- "${key[Insert]}" overwrite-mode
[[ -n "${key[Backspace]}" ]] && bindkey -- "${key[Backspace]}" backward-delete-char
[[ -n "${key[Delete]}" ]] && bindkey -- "${key[Delete]}" delete-char
-[[ -n "${key[Up]}" ]] && bindkey -- "${key[Up]}" up-line-or-history
-[[ -n "${key[Down]}" ]] && bindkey -- "${key[Down]}" down-line-or-history
[[ -n "${key[Left]}" ]] && bindkey -- "${key[Left]}" backward-char
[[ -n "${key[Right]}" ]] && bindkey -- "${key[Right]}" forward-char
[[ -n "${key[PageUp]}" ]] && bindkey -- "${key[PageUp]}" beginning-of-buffer-or-history
[[ -n "${key[PageDown]}" ]] && bindkey -- "${key[PageDown]}" end-of-buffer-or-history
[[ -n "${key[ShiftTab]}" ]] && bindkey -- "${key[ShiftTab]}" reverse-menu-complete
-# Finally, make sure the terminal is in application mode, when zle is
-# active. Only then are the values from $terminfo valid.
+# Application mode: terminfo values are only valid while the terminal is in
+# application mode. Enable it while zle is active.
if (( ${+terminfo[smkx]} && ${+terminfo[rmkx]} )); then
autoload -Uz add-zle-hook-widget
- function zle_application_mode_start {
- echoti smkx
- }
- function zle_application_mode_stop {
- echoti rmkx
- }
- add-zle-hook-widget -Uz zle-line-init zle_application_mode_start
- add-zle-hook-widget -Uz zle-line-finish zle_application_mode_stop
-fi
-
-if [ -n "$DISPLAY" ]; then
- function zle-line-init () { echoti smkx }
- function zle-line-finish () { echoti rmkx }
- zle -N zle-line-init
- zle -N zle-line-finish
+ function zle_application_mode_start { echoti smkx }
+ function zle_application_mode_stop { echoti rmkx }
+ add-zle-hook-widget -Uz zle-line-init zle_application_mode_start
+ add-zle-hook-widget -Uz zle-line-finish zle_application_mode_stop
fi
+# ── History search: Up/Down search by prefix ──────────────────────────────────
autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
-
[[ -n "${key[Up]}" ]] && bindkey -- "${key[Up]}" up-line-or-beginning-search
[[ -n "${key[Down]}" ]] && bindkey -- "${key[Down]}" down-line-or-beginning-search
+# ── Custom keybindings ────────────────────────────────────────────────────────
bindkey \^U backward-kill-line
-autoload -U select-word-style
-select-word-style bash
-
+# Ctrl-D exits even on non-empty line
exit_zsh() { exit }
zle -N exit_zsh
bindkey '^D' exit_zsh
-autoload -z edit-command-line
+# Ctrl-X Ctrl-E: edit command in $EDITOR
+autoload -Uz edit-command-line
zle -N edit-command-line
bindkey "^X^E" edit-command-line
-bash() {
- export USE_BASH="yes"
- command bash
-}
+# ── Word style ────────────────────────────────────────────────────────────────
+# Ctrl-W/Alt-B/Alt-F use shell quoting rules for word boundaries
+autoload -Uz select-word-style
+select-word-style shell
-setopt interactivecomments
+# ── Smart dot expansion ───────────────────────────────────────────────────────
+# Typing .. automatically expands: ... → ../.. , .... → ../../.. , etc.
+rationalise-dot() {
+ if [[ $LBUFFER = *.. ]]; then
+ LBUFFER+=/..
+ else
+ LBUFFER+=.
+ fi
+}
+zle -N rationalise-dot
+bindkey . rationalise-dot
+# ── Window title ──────────────────────────────────────────────────────────────
autoload -Uz add-zsh-hook
-xterm_title_precmd () {
- print -Pn -- '\e]2;%~\a'
-}
-
-xterm_title_preexec () {
- print -Pn -- '\e]2;%~ %# ' && print -n -- "${(q)1}\a"
-}
+xterm_title_precmd() { print -Pn -- '\e]2;%~\a' }
+xterm_title_preexec() { print -Pn -- '\e]2;%~ %# ' && print -n -- "${(q)1}\a" }
if [[ "$TERM" == (alacritty|st*|screen*|xterm*|rxvt*|tmux*|putty*|konsole*|gnome*) ]]; then
add-zsh-hook -Uz precmd xterm_title_precmd
add-zsh-hook -Uz preexec xterm_title_preexec
fi
-autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
+# ── Recent directories ────────────────────────────────────────────────────────
+autoload -Uz chpwd_recent_dirs cdr
add-zsh-hook chpwd chpwd_recent_dirs
zstyle ':completion:*:*:cdr:*:*' menu selection
-autoload -Uz run-help
+# ── Help system ───────────────────────────────────────────────────────────────
+autoload -Uz run-help run-help-git run-help-ip
+(( $+aliases[run-help] )) && unalias run-help
alias help=run-help
-autoload -Uz run-help-git
-autoload -Uz run-help-ip
-autoload -Uz run-help-sudo
-
-set zle_bracketed_paste # Explicitly restore this zsh default
+# ── Bracketed paste ───────────────────────────────────────────────────────────
autoload -Uz bracketed-paste-magic
zle -N bracketed-paste bracketed-paste-magic
-autoload -Uz select-word-style
-select-word-style shell
+# ── Aliases ───────────────────────────────────────────────────────────────────
+# Files
+alias l='lsd -l'
+alias la='lsd -lA'
+alias lt='lsd --tree'
+alias mkdir='mkdir -p'
+alias du='du -h'
+alias df='df -h'
+alias free='free -h'
-safesource /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
+# Grep / diff with color
+alias grep='grep --color=auto'
+alias fgrep='fgrep --color=auto'
+alias egrep='egrep --color=auto'
+alias diff='diff --color=auto'
+alias dmesg='dmesg --color=auto'
+alias dm='dmesg --color=always | less -r'
-if [ -n "$ZSH_HIGHLIGHT_STYLES" ]; then
- ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern)
- ZSH_HIGHLIGHT_STYLES[comment]='fg=yellow'
-fi
+# Networking
+alias ip="ip -color=auto"
+alias lsip="ip -human -color=auto --brief address show"
+alias ipa="ip -stats -details -human -color=auto address show"
+alias ipecho='curl ipecho.net/plain'
+alias ss='doas ss -tupnl'
+
+# Privilege escalation
+alias sudo='doas'
+alias sudoedit='doasedit'
+alias gimme='doas chown $USER:$(id -gn $USER)'
+alias pacdiff='doas pacdiff'
+
+# Pacman
+alias pacopt='comm -13 <(pacman -Qqdt | sort) <(pacman -Qqdtt | sort)'
+
+# Git
+alias g='git'
+
+# Systemd
+alias sys='systemctl'
+alias ssys='doas systemctl'
+alias sysu='systemctl --user'
+
+# Navigation
+alias ...='cd ../..'
+alias ....='cd ../../..'
+alias .....='cd ../../../..'
+alias c='clear'
-export ZSH_AUTOSUGGEST_USE_ASYNC=y
-safesource /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
-bindkey '^[[Z' autosuggest-accept
+# Tools
+alias stow='stow -R --no-folding --adopt'
+alias curl='curlie'
+alias xclip="xclip -selection clipboard -f"
+alias cpr='rsync --archive -hh --partial --info=stats1,progress2 --modify-window=1'
+alias mvr='rsync --archive -hh --partial --info=stats1,progress2 --modify-window=1 --remove-source-files'
+alias sub='subliminal download -l en'
-safesource /usr/share/zsh/plugins/zsh-history-substring-search/zsh-history-substring-search.zsh
+# Neovim
+alias n='nvim'
+alias ndiff='nvim -d'
+alias nd='nvim -d'
+alias nview='nvim -R'
+alias nv='nvim -R'
+alias ng='nvim +Neogit'
+# Tmux
+alias ta='tmux new-session -A'
+alias tas='tmux new-session -A -s'
+
+# Just
+alias j='just'
+
+# X11 keyboard inspection
+whichkey() {
+ xev | awk -F'[ )]+' '/^KeyPress/ { a[NR+2] } NR in a { printf "%-3s %s\n", $5, $8 }'
+}
+
+# LLVM / Clang tooling
+alias ncmake='cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_FLAGS="$DEV_CFLAGS" -DCMAKE_CXX_FLAGS="$DEV_CFLAGS" -DCMAKE_INSTALL_PREFIX=build/install -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build'
+alias ircc='clang -S -emit-llvm -fno-discard-value-names -O0 -Xclang -disable-O0-optnone -o -'
+alias irfc='flang -S -emit-llvm -O0 -o -'
+alias astcc='clang -Xclang -ast-dump -fsyntax-only'
+alias astfc='flang -fc1 -fdebug-dump-parse-tree'
+alias symfc='flang -fc1 -fdebug-dump-symbols'
+alias gdb='gdb -ex start --args'
+
+# GitHub Copilot CLI
+alias copilot='gh copilot --autopilot --enable-all-github-mcp-tools --yolo --resume'
+
+# ── Alias completions ─────────────────────────────────────────────────────────
+compdef g=git
+compdef j=just
+compdef n=nvim ndiff=nvim nd=nvim nview=nvim nv=nvim
+compdef sys=systemctl ssys=systemctl sysu=systemctl
+compdef l=lsd la=lsd lt=lsd
+
+# ── GPG agent ─────────────────────────────────────────────────────────────────
+# Refresh gpg-agent's TTY so pinentry prompts appear in the right terminal
+gpg-connect-agent updatestartuptty /bye &>/dev/null
+
+# ── FZF ───────────────────────────────────────────────────────────────────────
source <(fzf --zsh)
+# Ctrl-X Ctrl-R: search history with fzf and immediately execute
fzf-history-widget-accept() {
- fzf-history-widget
- zle accept-line
+ fzf-history-widget
+ zle accept-line
}
-zle -N fzf-history-widget-accept
+zle -N fzf-history-widget-accept
bindkey '^X^R' fzf-history-widget-accept
-_fzf_compgen_path() {
- fd --hidden --follow --exclude ".git" . "$1"
-}
+_fzf_compgen_path() { fd --hidden --follow --exclude ".git" . "$1" }
+_fzf_compgen_dir() { fd --type d --hidden --follow --exclude ".git" . "$1" }
-# Use fd to generate the list for directory completion
-_fzf_compgen_dir() {
- fd --type d --hidden --follow --exclude ".git" . "$1"
-}
+# ── Plugins (must be sourced last) ────────────────────────────────────────────
+source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
+ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern)
+ZSH_HIGHLIGHT_STYLES[comment]='fg=yellow'
-compdef g=git
-compdef j=just
-compdef n=nvim
-compdef ndiff=nvim
-compdef nd=nvim
-compdef nview=nvim
-compdef nv=nvim
-compdef sys=systemctl
-compdef ssys=systemctl
-compdef sysu=systemctl
-compdef l=lsd
-compdef la=lsd
-compdef lt=lsd
+source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
+bindkey '^[[Z' autosuggest-accept # Shift-Tab to accept suggestion
+
+source /usr/share/zsh/plugins/zsh-history-substring-search/zsh-history-substring-search.zsh