clipmenu

Simple clipboard management using dmenu
git clone https://git.sinitax.com/cdown/clipmenu
Log | Files | Refs | README | LICENSE | sfeed.txt

commit 6edf3c437bb9bafb41e0e7383ff4def6a794cd13
parent f0fe96955af9bb0bacea06b93752fe51c72d3024
Author: Chris Down <chris@chrisdown.name>
Date:   Fri,  6 Jan 2017 14:02:47 +0000

perf: Add naive but performant path

Diffstat:
Mclipmenu | 35+++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/clipmenu b/clipmenu @@ -3,17 +3,10 @@ shopt -s nullglob # We use this to make sure the cache files are sorted bytewise -LC_COLLATE=C - -declare -A selections +export LC_COLLATE=C cache_file=/tmp/clipmenu.$USER/line_cache -# We use tac since we want newest to oldest, and we append in clipmenud -while IFS='|' read -r full_file first_line; do - selections[$first_line]=$full_file -done < <(tac "$cache_file") - # 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 @@ -22,10 +15,32 @@ chosen_line=$(sed 's/^[^|]\+|//' "$cache_file" | tac | uniq | dmenu -l 8 "$@") [[ $chosen_line ]] || exit 1 +# Naive, but performant path, only follow expensive path if it doesn't work +out_line=$(grep -F "|$chosen_line" "$cache_file") +out_length=$(wc -l <<< "$out_line") + +if (( out_length == 1 )); then + # Cheap path succeded + file=${out_line%%|*} +elif (( out_length > 1 )); then + # Cheap path failed + while IFS='|' read -r full_file first_line; do + if [[ $first_line == "$chosen_line" ]]; then + file=$full_file + break + fi + done <<< "$out_line" +else + # We didn't find this in cache + printf 'FATAL: %s not in cache, run clipmenu-fsck\n' "$chosen_line" >&2 + exit 2 +fi + + for selection in clipboard primary; do if type -p xsel >/dev/null 2>&1; then - xsel -i --"$selection" < "${selections[$chosen_line]}" + xsel -i --"$selection" < "$file" else - xclip -sel "$selection" < "${selections[$chosen_line]}" + xclip -sel "$selection" < "$file" fi done