diff --git a/.local/bin/filterHistory b/.local/bin/filterHistory index 6229bff..f806331 100755 --- a/.local/bin/filterHistory +++ b/.local/bin/filterHistory @@ -12,30 +12,39 @@ [ -e "$1" ] || { echo "File does not exist" >&2; exit 1; } [ "$(stat -c '%a' "$1")" = "600" ] || { echo "File does not look like a history file" >&2; exit 1; } -declare -a COMMANDS -COMMANDS=('ls' \ - 'll' \ - 'l' \ - ':q' \ - ':Q' \ - 'exit' \ - 'cd' \ - 'cd ~' \ - 'cd .' \ - 'cd ..' \ - 'gs' \ - 'git status' \ - 'gd' \ - 'gpush' \ - 'git pull' \ - 'cmake .. && make' \ - 'exec zsh' \ - 'python3' \ - 'clear' \ -) +# Sort the commands per number of occurrences +most_used="$(\ + cut -d';' -f2 "$1" \ + | sort \ + | uniq -c \ + | sort -nr \ +)" -printf '%s\n' "${COMMANDS[@]}" | column -echo "Are you a 100% sure you want to delete these commands from $1? (Type out yes)" +declare -a commands +if command -v fzf >/dev/null 2>&1; then + # Let the user pick in fzf from the most used commands + readarray -t commands < <(\ + fzf -m --reverse --height 50% <<<"$most_used" \ + | sed -E 's/^[ \t]*[0-9]+ //' \ + ) +else + echo "Most used commands:" + offset="$(head -1 <<<"$most_used" | sed -E 's/^( *[0-9]+).*$/\1/' | wc -m)" + for (( i = 0; i < $offset - $(wc -m <<<"count"); i++ )); do + echo -n " " + done + echo "count command" + head <<<"$most_used" + echo -n "You do not have fzf installed. Please type out the commands you" + echo -n " want to delete manually and finish by pressing Ctrl+D." + echo + readarray commands + echo +fi + +[ "${#commands}" -gt 0 ] || exit 0 +printf '%s\n' "${commands[@]}" | column -x +echo "Please confirm the deletion of these commands in $1 ('yes')" read yn [ "$yn" = "yes" ] || exit 1 @@ -44,9 +53,15 @@ cp "$1" "$tempd/$(basename "$1")" echo "Backup created at $tempd/$(basename "$1")" echo -for c in "${COMMANDS[@]}"; do - c="$(echo "$c" | sed 's/\./\\./g; s/\//\\\//g')" - sed -Ei "/^: [0-9]+:[0-9]+;${c}\$/d" "$1" +for c in "${commands[@]}"; do + # Escape all characters that sed could misinterpret. + pattern="^: [0-9]+:[0-9]+;$(sed -E 's/[./?+|()*\\]|\[|\]/\\&/g' <<<"$c")\$" + # Find first occurrence of the command in the history file + first="$(grep -Enm1 "$pattern" "$1" | cut -d: -f1)" + + # Delete all lines beginning from the line after the first occurrence that + # contain (exactly) the command. + sed -Ei "$((first + 1)),\$ { /$pattern/d }" "$1" echo "$c deleted" done