clipmenu-spmenu/clipmenu
Chris Down f22fce7f04 Use a single line cache file
In c7c894a0, a per-selection line-cache was introduced in order to
overcome some of the limitations of clipmenu at the time (for example,
missing duplicate detection). However, now we have all the features we
need to have a single line cache again, and having multiple line caches
has caused more trouble than it is worth.

For example, maintaining CM_MAX_CLIPS globally is extremely cumbersome,
so we don't do it, and CM_MAX_CLIPS is actually acted on per-selection.
We also have had bugs where we perform actions on cache files without
properly consulting other line caches, and while those can be fixed, the
simplest thing to do now is just to go back to having a single line
cache.
2020-03-23 13:00:14 +00:00

71 lines
1.8 KiB
Bash
Executable file

#!/usr/bin/env bash
: "${CM_LAUNCHER=dmenu}"
: "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}"
: "${CM_HISTLENGTH=8}"
major_version=6
shopt -s nullglob
cache_dir=$CM_DIR/clipmenu.$major_version.$USER
cache_file=$cache_dir/line_cache
if [[ $1 == --help ]] || [[ $1 == -h ]]; then
cat << 'EOF'
clipmenu is a simple clipboard manager using dmenu and xsel. Launch this
when you want to select a clip.
All arguments are passed through to dmenu itself.
Environment variables:
- $CM_DIR: specify the base directory to store the cache dir in (default: $XDG_RUNTIME_DIR, $TMPDIR, or /tmp)
- $CM_HISTLENGTH: specify the number of lines to show in dmenu/rofi (default: 8)
- $CM_LAUNCHER: specify a dmenu-compatible launcher (default: dmenu)
EOF
exit 0
fi
if [[ "$CM_LAUNCHER" == rofi ]]; then
# rofi supports dmenu-like arguments through the -dmenu flag
set -- -dmenu "$@"
fi
list_clips() {
LC_ALL=C sort -rnk 1 < "$cache_file" | cut -d' ' -f2- | awk '!seen[$0]++'
}
if [[ "$CM_LAUNCHER" == rofi-script ]]; then
if ! (( $# )); then
list_clips
exit
else
# https://github.com/koalaman/shellcheck/issues/1141
# shellcheck disable=SC2124
chosen_line="${@: -1}"
fi
else
chosen_line=$(
list_clips | "$CM_LAUNCHER" -l "${CM_HISTLENGTH}" "$@"
)
fi
[[ $chosen_line ]] || exit 1
file=$cache_dir/$(cksum <<< "$chosen_line")
if ! [[ -f "$file" ]]; then
# We didn't find this in cache
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" >&2
grep -nFR "$chosen_line" "$cache_dir" >&2
stat "$file" >&2
exit 2
fi
for selection in clipboard primary; do
xsel --logfile /dev/null -i --"$selection" < "$file"
done