From 7212ed8f2e355856b456b0c83e8a1ebe5a62d71d Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Fri, 22 May 2026 10:41:21 +0100 Subject: feat(zsh): enrich pacopt with reverse-optdep info Promote pacopt from a plain alias to a function. In addition to listing packages that remain installed solely as someone's optional dependency, each package is now annotated with its parent(s) and the upstream reason text from the parent's Optional Deps field. Implementation is pacman-only (no expac): one awk pass over 'pacman -Qi' builds a reverse index of every (parent, optdep, reason) edge in the local DB, then per leaf package the index is filtered for matching deps. --- dot_config/zsh/dot_zshrc | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'dot_config/zsh/dot_zshrc') diff --git a/dot_config/zsh/dot_zshrc b/dot_config/zsh/dot_zshrc index 99f67f3..2eea559 100644 --- a/dot_config/zsh/dot_zshrc +++ b/dot_config/zsh/dot_zshrc @@ -239,7 +239,41 @@ alias gimme='sudo chown $USER:$(id -gn $USER)' alias pacdiff='sudo pacdiff' # Pacman -alias pacopt='comm -13 <(pacman -Qqdt | sort) <(pacman -Qqdtt | sort)' +# List packages installed only because they are someone's *optional* dep +# (no package strictly requires them), and for each one show the parent +# package(s) that list it as an Optional Dep along with the upstream reason. +pacopt() { + local -a leaves + leaves=( ${(f)"$(comm -13 <(pacman -Qqdt | sort) <(pacman -Qqdtt | sort))"} ) + (( ${#leaves[@]} )) || return 0 + # One pass over `pacman -Qi`: emit "depparentreason" lines + # for every (parent, optional-dep) edge in the local DB. + local index + index=$(pacman -Qi 2>/dev/null | awk ' + function emit(line, parent, n, dep, reason) { + sub(/^ +/, "", line); sub(/ \[installed\]$/, "", line) + n = index(line, ":") + if (n) { dep = substr(line, 1, n-1); reason = substr(line, n+2); sub(/^ +/, "", reason) } + else { dep = line; reason = "" } + print dep "\t" parent "\t" reason + } + /^Name +:/ { name=$3; in_od=0; next } + /^Optional Deps +:/ { + sub(/^[^:]*: */, "") + if ($0 == "None") { in_od=0; next } + in_od=1; emit($0, name); next + } + /^[A-Z][a-z]+[a-zA-Z ]*: / { in_od=0; next } + in_od && NF { emit($0, name) } + ') + local p + for p in "${leaves[@]}"; do + print -P -- "%B${p}%b" + print -r -- "$index" | awk -F'\t' -v p="$p" ' + $1 == p { printf " ← %s%s\n", $2, ($3 ? ": " $3 : "") } + ' + done +} # Git alias g='git' -- cgit v1.3.1