From f22fce7f0407b6ace997599827b9f9ab01ad5c3f Mon Sep 17 00:00:00 2001 From: Chris Down Date: Mon, 23 Mar 2020 12:28:37 +0000 Subject: [PATCH] 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. --- .travis.yml | 2 +- clipdel | 28 ++++++++++++---------------- clipfsck | 12 ++++++------ clipmenu | 8 ++++---- clipmenud | 5 ++--- tests/test-clipmenu | 4 ++-- tests/test-perf | 4 ++-- 7 files changed, 29 insertions(+), 34 deletions(-) diff --git a/.travis.yml b/.travis.yml index d2c7146..cf0c2a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: bash dist: xenial script: - - shellcheck -s bash clipmenu clipmenud + - shellcheck -s bash clipmenu clipmenud clipdel clipfsck - tests/test-clipmenu matrix: diff --git a/clipdel b/clipdel index 028d011..7265711 100755 --- a/clipdel +++ b/clipdel @@ -7,12 +7,12 @@ if [[ $1 == -d ]]; then shift fi -major_version=5 +major_version=6 shopt -s nullglob cache_dir=$CM_DIR/clipmenu.$major_version.$USER -cache_file_prefix=$cache_dir/line_cache +cache_file=$cache_dir/line_cache lock_file=$cache_dir/lock lock_timeout=2 @@ -35,10 +35,8 @@ 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 +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 @@ -64,7 +62,7 @@ if (( CM_REAL_DELETE )) && [[ "$raw_pattern" == ".*" ]]; then exit 0 else mapfile -t matches < <( - sed -n "${sed_common_command}p" "${line_cache_files[@]}" | + sed -n "${sed_common_command}p" "$cache_file" | sort -u ) @@ -76,15 +74,13 @@ else rm -f -- "$cache_dir/$ck" done - for file in "${line_cache_files[@]}"; do - 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" "$file" > "$temp" - mv -- "$temp" "$file" - 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 diff --git a/clipfsck b/clipfsck index 78f1725..b2d7f59 100755 --- a/clipfsck +++ b/clipfsck @@ -2,12 +2,12 @@ : "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}" -major_version=5 +major_version=6 shopt -s nullglob cache_dir=$CM_DIR/clipmenu.$major_version.$USER -cache_file_prefix=$cache_dir/line_cache +cache_file=$cache_dir/line_cache declare -A cksums @@ -16,11 +16,11 @@ while IFS= read -r line; do cksums["$cksum"]="$line" # Are all cache entries represented by a file? - cache_file=$cache_dir/$cksum - if ! [[ -f $cache_file ]]; then - printf 'cache entry without file: %s -> %s\n' "$line" "$cache_file" >&2 + full_file=$cache_dir/$cksum + if ! [[ -f $full_file ]]; then + printf 'cache entry without file: %s -> %s\n' "$line" "$full_file" >&2 fi -done < <(cat "$cache_file_prefix"_* /dev/null | cut -d' ' -f2-) +done < <(cut -d' ' -f2- < "$cache_file") # Are all files represented by a cache entry? for file in "$cache_dir"/[012346789]*; do diff --git a/clipmenu b/clipmenu index c085eab..309a224 100755 --- a/clipmenu +++ b/clipmenu @@ -4,12 +4,12 @@ : "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}" : "${CM_HISTLENGTH=8}" -major_version=5 +major_version=6 shopt -s nullglob cache_dir=$CM_DIR/clipmenu.$major_version.$USER -cache_file_prefix=$cache_dir/line_cache +cache_file=$cache_dir/line_cache if [[ $1 == --help ]] || [[ $1 == -h ]]; then cat << 'EOF' @@ -33,7 +33,7 @@ if [[ "$CM_LAUNCHER" == rofi ]]; then fi list_clips() { - cat "$cache_file_prefix"_* /dev/null | LC_ALL=C sort -rnk 1 | cut -d' ' -f2- | awk '!seen[$0]++' + LC_ALL=C sort -rnk 1 < "$cache_file" | cut -d' ' -f2- | awk '!seen[$0]++' } if [[ "$CM_LAUNCHER" == rofi-script ]]; then @@ -59,7 +59,7 @@ 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_prefix"_* >&2 + wc -l "$cache_file" >&2 grep -nFR "$chosen_line" "$cache_dir" >&2 stat "$file" >&2 exit 2 diff --git a/clipmenud b/clipmenud index 6d32604..f8ad06b 100755 --- a/clipmenud +++ b/clipmenud @@ -15,9 +15,9 @@ CM_MAX_CLIPS_THRESH=$(( CM_MAX_CLIPS + 100 )) # shellcheck disable=SC2153 : "${CM_SELECTIONS=clipboard primary}" -major_version=5 +major_version=6 cache_dir=$CM_DIR/clipmenu.$major_version.$USER/ -cache_file_prefix=$cache_dir/line_cache +cache_file=$cache_dir/line_cache # lock_file is the lock for *one* iteration of clipboard capture/propagation. # session_lock_file is the lock to prevent multiple clipmenud daemons from @@ -186,7 +186,6 @@ while true; do fi for selection in "${cm_selections[@]}"; do - cache_file=${cache_file_prefix}_$selection data=$(_xsel -o --"$selection"; printf x) debug "Data before stripping: $data" diff --git a/tests/test-clipmenu b/tests/test-clipmenu index 7189666..45d8c65 100755 --- a/tests/test-clipmenu +++ b/tests/test-clipmenu @@ -6,9 +6,9 @@ set -o pipefail : "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}" -major_version=5 +major_version=6 dir=$CM_DIR/clipmenu.$major_version.$USER -cache_file=$dir/line_cache_primary +cache_file=$dir/line_cache if [[ $0 == /* ]]; then location=${0%/*} diff --git a/tests/test-perf b/tests/test-perf index 6866313..141197f 100755 --- a/tests/test-perf +++ b/tests/test-perf @@ -1,6 +1,6 @@ #!/usr/bin/env bash -major_version=5 +major_version=6 msg() { printf '>>> %s\n' "$@" >&2 @@ -9,7 +9,7 @@ msg() { : "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}" dir=$CM_DIR/clipmenu.$major_version.$USER -cache_file=$dir/line_cache_primary +cache_file=$dir/line_cache log=$(mktemp) tim=$(mktemp)