Merge branch 'release/5.2.0'
This commit is contained in:
commit
8388a00ab3
|
@ -21,6 +21,8 @@ invoke clipmenu in exactly the same way to get the same effect, like so:
|
||||||
|
|
||||||
clipmenu -i -fn Terminus:size=8 -nb '#002b36' -nf '#839496' -sb '#073642' -sf '#93a1a1'
|
clipmenu -i -fn Terminus:size=8 -nb '#002b36' -nf '#839496' -sb '#073642' -sf '#93a1a1'
|
||||||
|
|
||||||
|
You can remove clips with the `clipdel` utility, see `clipdel --help`.
|
||||||
|
|
||||||
# How does it work?
|
# How does it work?
|
||||||
|
|
||||||
The code is fairly simple and easy to follow, you may find it easier to read
|
The code is fairly simple and easy to follow, you may find it easier to read
|
||||||
|
|
79
clipdel
Executable file
79
clipdel
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
: "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}"
|
||||||
|
CM_REAL_DELETE=0
|
||||||
|
[[ $1 == -d ]] && CM_REAL_DELETE=1
|
||||||
|
|
||||||
|
major_version=5
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
cache_dir=$CM_DIR/clipmenu.$major_version.$USER
|
||||||
|
cache_file_prefix=$cache_dir/line_cache
|
||||||
|
lock_file=$cache_dir/lock
|
||||||
|
lock_timeout=2
|
||||||
|
|
||||||
|
if [[ $1 == --help ]] || [[ $1 == -h ]]; then
|
||||||
|
cat << 'EOF'
|
||||||
|
clipdel deletes clipmenu entries matching a regex. By default, just lists what
|
||||||
|
it would delete, pass -d to do it for real.
|
||||||
|
|
||||||
|
".*" 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
|
||||||
|
|
||||||
|
line_cache_files=( "$cache_file_prefix"_* )
|
||||||
|
|
||||||
|
if (( ${#line_cache_files[@]} == 0 )); then
|
||||||
|
printf '%s\n' "No line cache files found, no clips exist" >&2
|
||||||
|
exit 0 # Well, this is a kind of success...
|
||||||
|
fi
|
||||||
|
|
||||||
|
# https://github.com/koalaman/shellcheck/issues/1141
|
||||||
|
# shellcheck disable=SC2124
|
||||||
|
raw_pattern=${@: -1}
|
||||||
|
esc_pattern=${raw_pattern/\#/'\#'}
|
||||||
|
|
||||||
|
exec {lock_fd}> "$lock_file"
|
||||||
|
|
||||||
|
if (( CM_REAL_DELETE )) && [[ "$raw_pattern" == ".*" ]]; then
|
||||||
|
flock -x -w "$lock_timeout" "$lock_fd" || exit
|
||||||
|
rm -rf -- "$cache_dir"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
mapfile -t matches < <(
|
||||||
|
cat "${line_cache_files[@]}" | cut -d' ' -f2- | sort -u |
|
||||||
|
sed -n "\\#${esc_pattern}#p"
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
for file in "${line_cache_files[@]}"; do
|
||||||
|
temp=$(mktemp)
|
||||||
|
cut -d' ' -f2- < "$file" | sed "\\#${esc_pattern}#d" > "$temp"
|
||||||
|
mv -- "$temp" "$file"
|
||||||
|
done
|
||||||
|
|
||||||
|
flock -u "$lock_fd"
|
||||||
|
else
|
||||||
|
if (( ${#matches[@]} )); then
|
||||||
|
printf '%s\n' "${matches[@]}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
36
clipmenu
36
clipmenu
|
@ -30,14 +30,28 @@ if [[ "$CM_LAUNCHER" == rofi ]]; then
|
||||||
set -- -dmenu "$@"
|
set -- -dmenu "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# It's okay to hardcode `-l 8` here as a sensible default without checking
|
list_clips() {
|
||||||
# whether `-l` is also in "$@", because the way that dmenu works allows a later
|
cat "$cache_file_prefix"_* /dev/null | LC_ALL=C sort -rnk 1 | cut -d' ' -f2- | awk '!seen[$0]++'
|
||||||
# argument to override an earlier one. That is, if the user passes in `-l`, our
|
}
|
||||||
# one will be ignored.
|
|
||||||
chosen_line=$(
|
if [[ "$CM_LAUNCHER" == rofi-script ]]; then
|
||||||
cat "$cache_file_prefix"_* /dev/null | LC_ALL=C sort -rnk 1 |
|
if ! (( $# )); then
|
||||||
cut -d' ' -f2- | awk '!seen[$0]++' | "$CM_LAUNCHER" -l 8 "$@"
|
list_clips
|
||||||
)
|
exit
|
||||||
|
else
|
||||||
|
# https://github.com/koalaman/shellcheck/issues/1141
|
||||||
|
# shellcheck disable=SC2124
|
||||||
|
chosen_line="${@: -1}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# It's okay to hardcode `-l 8` here as a sensible default without checking
|
||||||
|
# whether `-l` is also in "$@", because the way that dmenu works allows a later
|
||||||
|
# argument to override an earlier one. That is, if the user passes in `-l`, our
|
||||||
|
# one will be ignored.
|
||||||
|
chosen_line=$(
|
||||||
|
list_clips | "$CM_LAUNCHER" -l 8 "$@"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
[[ $chosen_line ]] || exit 1
|
[[ $chosen_line ]] || exit 1
|
||||||
|
|
||||||
|
@ -45,7 +59,11 @@ file=$cache_dir/$(cksum <<< "$chosen_line")
|
||||||
|
|
||||||
if ! [[ -f "$file" ]]; then
|
if ! [[ -f "$file" ]]; then
|
||||||
# We didn't find this in cache
|
# We didn't find this in cache
|
||||||
printf 'FATAL: %s not in cache\n' "$chosen_line" >&2
|
printf 'FATAL: %s not in cache (%s missing)\n' "$chosen_line" "$file" >&2
|
||||||
|
printf 'Please report the following debug information:\n\n' >&2
|
||||||
|
wc -l "$cache_file_prefix"_* >&2
|
||||||
|
grep -nFR "$chosen_line" "$cache_dir" >&2
|
||||||
|
stat "$file" >&2
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
12
clipmenud
12
clipmenud
|
@ -181,15 +181,21 @@ while true; do
|
||||||
rm -- "${last_filename[$selection]}"
|
rm -- "${last_filename[$selection]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
last_data[$selection]=$data
|
|
||||||
last_filename[$selection]=$filename
|
|
||||||
|
|
||||||
first_line=$(get_first_line "$data")
|
first_line=$(get_first_line "$data")
|
||||||
|
|
||||||
debug "New clipboard entry on $selection selection: \"$first_line\""
|
debug "New clipboard entry on $selection selection: \"$first_line\""
|
||||||
|
|
||||||
cache_file_output="$(date +%s%N) $first_line"
|
cache_file_output="$(date +%s%N) $first_line"
|
||||||
filename="$cache_dir/$(cksum <<< "$first_line")"
|
filename="$cache_dir/$(cksum <<< "$first_line")"
|
||||||
|
|
||||||
|
last_data[$selection]=$data
|
||||||
|
last_filename[$selection]=$filename
|
||||||
|
|
||||||
|
# Recover without restart if we deleted the entire clip dir.
|
||||||
|
# It's ok that this only applies to the final directory.
|
||||||
|
# shellcheck disable=SC2174
|
||||||
|
mkdir -p -m0700 "$cache_dir"
|
||||||
|
|
||||||
debug "Writing $data to $filename"
|
debug "Writing $data to $filename"
|
||||||
printf '%s' "$data" > "$filename"
|
printf '%s' "$data" > "$filename"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue