fzf chooser instead of hardcoded commands

Instead of deleting hardcoded commands in filterHistory, sort commands
by usage and let the user select in fzf. If fzf is not installed, show
the most used ones and let the user select manually.
Keep the first occurence in the history for stuff like autosuggestions.
This commit is contained in:
2020-09-03 11:39:32 +02:00
parent 292b45aefb
commit 0bd083f760

View File

@@ -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