clipd (1672B)
1 #!/bin/sh 2 3 CD_MAX_CLIP=1000 4 CD_MAX_CLIP_THRESH=$((CD_MAX_CLIP + 100)) 5 6 last_id="" 7 8 die() { 9 echo "$@" 10 exit 1 11 } 12 13 empty() { 14 case "$1" in 15 *[![:blank:]]*) return 1;; 16 *) return 0;; 17 esac 18 } 19 20 partof() { 21 [ -z "$1" ] && return 1; 22 [ -z "$2" ] && return 1; 23 case "$1" in 24 *"$2") return 0;; 25 "$2"*) return 0;; 26 esac 27 case "$2" in 28 *"$1") return 0;; 29 "$1"*) return 0;; 30 esac 31 return 1; 32 } 33 34 getid() { 35 echo "$(echo "$@" | md5sum | cut -d' ' -f1)" 36 } 37 38 [ -z "$1" ] && die "selection is missing" 39 selection="$1" 40 41 cachedir="/tmp/.clipd/$USER/" 42 43 # check prerequisites 44 command -v clipnotify >/dev/null 2>&1 || die "'clipnotify' program is missing" 45 command -v timeout >/dev/null 2>&1 || die "'timeout' program is missing" 46 command -v xsel >/dev/null 2>&1 || die "'xsel' program is missing" 47 48 case "$selection" in 49 primary|secondary|clipboard);; 50 *) die "'$selection' is not a valid selection"; 51 esac 52 53 while clipnotify; do 54 data="$(timeout 1 xsel --logfile /dev/null -o --"$selection")" 55 56 # check if empty 57 empty "$data" && continue 58 59 # check if identical to last 60 [ "$data" = "$last_entry" ] && continue 61 62 # check if last or current are parts of each other, and delete last if so. 63 if partof "$data" "$last_entry"; then 64 rm -- "/tmp/.clipd/$USER/$last_id" 65 fi 66 67 last_id="$selection.$(getid "$data")" 68 last_entry="$data" 69 70 mkdir -m0700 -p -- "/tmp/.clipd/$USER/" 71 echo "$data" > "/tmp/.clipd/$USER/$last_id" 72 chmod 600 -- "/tmp/.clipd/$USER/$last_id" 73 74 # remove old entries if threshold is met 75 if [ ! -z "$CD_MAX_CLIP" ] && \ 76 [ "$(ls "/tmp/.clipd/$USER/" | wc -l)" -gt "$CD_MAX_CLIP_THRESH" ]; then 77 ls -dt "/tmp/.clipd/$USER/"* | sed -e "1,${CD_MAX_CLIP}d" \ 78 | xargs -d '\n' rm 79 fi 80 done