function history_prune --description 'Prune old, easily retyped commands from history' argparse h/help a/apply 'd/days=!_validate_int --min 1' -- $argv; or return if set -q _flag_help echo 'Usage: history_prune [-d DAYS] [-a]' echo 'Lists old disposable entries (dry run); -a deletes them. Default age: 90 days.' return end set -q _flag_days; or set _flag_days 90 set -l cutoff (math (date +%s) - $_flag_days \* 86400) # Trivial commands: always dropped once old (optional doas prefix) set -l trivial '^(doas )?(cd|ls|ll|cat|less|man|vim|vimdiff|du|ps|kill|which|file|echo|rm|rmdir|mv|cp|mkdir|grep|history)( |$)' # One-off invocations of tools: the newest one per two-word prefix is kept as a template set -l oneoff (string join '' '^(doas )?(beet|pacman -(Q[a-z]*|S[si])|aur (search|fetch)|' \ '(git|config) (add|commit|restore|checkout|status|diff|log|show)|' \ 'systemctl( --user)? status|shnsplit|cuetag\.sh|flac2all|hyperfine|stack run)( |$)') set -l seen set -l doomed # Newest first, so the first match of a prefix is its most recent use for e in (history search --show-time='%s|' --null | string split0) set -l t (string split -m1 '|' -- $e) set -l cmd $t[2] set -l old (test $t[1] -lt $cutoff; and echo 1) if string match -qr -- $oneoff $cmd # Prefix is the command plus its subcommand/flag, if any (not a path or quoted arg) set -l w (string split -n ' ' -- (string replace -r '^doas ' '' -- $cmd)) set -l prefix $w[1] string match -qr '^-?-?[a-zA-Z][a-zA-Z-]*$' -- "$w[2]"; and set prefix "$w[1..2]" if not contains -- $prefix $seen set -a seen $prefix continue end set -q old[1]; and set -a doomed $cmd else if set -q old[1]; and begin test (string length -- $cmd) -lt 20; or string match -qr -- $trivial $cmd end set -a doomed $cmd end end if not set -q _flag_apply printf '%s\n' $doomed echo (count $doomed) "entries would be removed (run with -a to apply)" >&2 return end test (count $doomed) -gt 0; or return set -l hist ~/.local/share/fish/fish_history cp $hist $hist.bak history delete --exact --case-sensitive -- $doomed echo (count $doomed) "entries removed; backup at $hist.bak" >&2 end