mirror of
https://github.com/The-Repo-Club/DotFiles.git
synced 2024-11-25 00:38:20 -05:00
102 lines
2.8 KiB
Bash
Executable File
102 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Path - /usr/bin/clipmenu-del
|
|
# GitHub - https://github.com/The-Repo-Club/
|
|
# Author - The-Repo-Club [wayne6324@gmail.com]
|
|
# Start On - Tue 05 Oct 16:09:16 BST 2021
|
|
# Modified On - Sun 31 Oct 00:30:32 BST 2021
|
|
#------------------------------------------------------------------------------
|
|
|
|
CM_REAL_DELETE=0
|
|
if [[ $1 == -d ]]; then
|
|
CM_REAL_DELETE=1
|
|
shift
|
|
fi
|
|
|
|
shopt -s nullglob
|
|
|
|
cache_dir=$(clipmenu-ctl cache-dir)
|
|
cache_file=$cache_dir/line_cache
|
|
lock_file=$cache_dir/lock
|
|
lock_timeout=2
|
|
|
|
if [[ $1 == --help ]] || [[ $1 == -h ]]; then
|
|
cat << 'EOF'
|
|
clipmenu-del deletes clipmenu entries matching a regex. By default, just lists what
|
|
it would delete, pass -d to do it for real. If no pattern is passed as an argument,
|
|
it will try to read one from standard input.
|
|
|
|
".*" is special, it will just nuke the entire data directory, including the
|
|
line caches and all other state.
|
|
|
|
Arguments:
|
|
|
|
-d Delete for real.
|
|
|
|
Environment variables:
|
|
|
|
- $CM_DIR: specify the base directory to store the cache dir in (default: $XDG_RUNTIME_DIR, $TMPDIR, or /tmp)
|
|
EOF
|
|
exit 0
|
|
fi
|
|
|
|
if ! [[ -f $cache_file ]]; then
|
|
printf '%s\n' "No line cache file found, no clips exist" >&2
|
|
exit 0 # Well, this is a kind of success...
|
|
fi
|
|
|
|
if [[ -n $1 ]]; then
|
|
raw_pattern=$1
|
|
elif ! [[ -t 0 ]]; then
|
|
IFS= read -r raw_pattern
|
|
fi
|
|
|
|
esc_pattern=${raw_pattern//\#/'\#'}
|
|
|
|
# We use 2 separate sed commands so "esc_pattern" matches only the 'clip' text
|
|
# without the timestamp (e.g. $> clipmenu-del '^delete_exact_match$')
|
|
sed_common_command="s#^[0-9]\+ ##;\\#${esc_pattern}#"
|
|
|
|
if ! [[ $raw_pattern ]]; then
|
|
printf '%s\n' 'No pattern provided, see --help' >&2
|
|
exit 2
|
|
fi
|
|
|
|
exec {lock_fd}> "$lock_file"
|
|
|
|
if (( CM_REAL_DELETE )) && [[ "$raw_pattern" == ".*" ]]; then
|
|
flock -x -w "$lock_timeout" "$lock_fd" || exit
|
|
rm -rf -- "$cache_dir"
|
|
mkdir -p -- "$cache_dir"
|
|
exit 0
|
|
else
|
|
mapfile -t matches < <(
|
|
sed -n "${sed_common_command}p" "$cache_file" |
|
|
sort -u
|
|
)
|
|
|
|
if (( CM_REAL_DELETE )); then
|
|
flock -x -w "$lock_timeout" "$lock_fd" || exit
|
|
|
|
for match in "${matches[@]}"; do
|
|
ck=$(cksum <<< "$match")
|
|
rm -f -- "$cache_dir/$ck"
|
|
done
|
|
|
|
temp=$(mktemp)
|
|
# sed 'h' and 'g' here means save and restore the line, so
|
|
# timestamps are not removed from non-deleted lines. 'd' deletes the
|
|
# line and restarts, skipping 'g'/restore.
|
|
# https://www.gnu.org/software/sed/manual/html_node/Other-Commands.html#Other-Commands
|
|
sed "h;${sed_common_command}d;g" "$cache_file" > "$temp"
|
|
mv -- "$temp" "$cache_file"
|
|
|
|
flock -u "$lock_fd"
|
|
else
|
|
if (( ${#matches[@]} )); then
|
|
printf '%s\n' "${matches[@]}"
|
|
fi
|
|
fi
|
|
fi
|