Add fish history filtering and monthly pruning

This commit is contained in:
Daniele Fucini
2026-10-14 11:09:24 +02:00
parent 7209834c0f
commit 8bf32a2744
4 changed files with 72 additions and 0 deletions
@@ -0,0 +1,5 @@
function fish_should_add_to_history
# Skip trivial commands that aren't worth recalling
string match -qr '^(doas )?(ls|ll|pwd|clear|exit|cd \.\.)( |$)' -- $argv; and return 1
return 0
end
+52
View File
@@ -0,0 +1,52 @@
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