-
Notifications
You must be signed in to change notification settings - Fork 1
/
clipmanager
executable file
·158 lines (138 loc) · 5.21 KB
/
clipmanager
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/bin/sh
history_dir="${XDG_CACHE_HOME:-$HOME/.cache}/clipboard_history/"
history_max_size=1000
pref_type="application/xournal
application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"
image/png
image/jpeg
image/bmp
x-special/gnome-copied-files
text/plain;charset=utf-8
"
default_string="UTF8_STRING"
log_to_file=1
log_file_path="${XDG_CACHE_HOME:-$HOME/.cache}/clipmanager.log"
lock_file_path="${XDG_CACHE_HOME:-$HOME/.cache}/clipmanager.lock"
history_current_size=0
disabled=0
log()
{
if [ "$log_to_file" -ne 0 ]; then
printf "%s\n" "$1" | xargs >>"$log_file_path"
fi
printf "\033[31m->\033[97m %s\033[0m\n" "$1" | xargs
}
# check if clipmanager is already running
if [ -d "$history_dir" ]; then
if [ -f "$lock_file_path" ]; then
lock_file_pid=$(cat "$lock_file_path")
if [ -d "/proc/$lock_file_pid" ] && [ "$(grep -o "^Name:.*$" "/proc/$lock_file_pid/status" | awk '{print $2}')" = "clipmanager" ]; then
log "Clipmanager is already running"
exit 1
else
rm -r "$history_dir"
fi
else
rm -r "$history_dir"
fi
fi
mkdir "$history_dir"
echo "$$" >"$lock_file_path"
# check if log file exists from previous session and rename it
if [ "$log_to_file" -ne 0 ] && [ -f "$log_file_path" ]; then
mv "$log_file_path" "$log_file_path.old"
fi
dep_ck()
{
for pr; do
if ! command -v "$pr" >/dev/null 2>&1; then
log "command $pr not found, install $pr"
exit 1
fi
done
}
dep_ck "xclip" "sha256sum"
clean_up()
{
rm -r "$history_dir"
rm "$lock_file_path"
exit
}
trap "exit" INT TERM
trap "clean_up" EXIT
trap "disabled=1" USR1
trap "disabled=0" USR2
log "$(basename "$0")"
log "----------"
while true; do
# target check
targets=$(xclip -selection clipboard -o -t TARGETS)
targets_exit=$?
log "TARGETS check: $targets_exit"
if [ "$targets_exit" -ne 0 ]; then
# if target check fails wait for another copy event
log "Waiting for selection with: $default_string"
xclip -verbose -selection clipboard -t "$default_string" -in </dev/null || exit 1
else
# if target check succeeds take ownership of clipboard and create a history entry
log "TARGETS clipboard: $targets"
log "TARGETS preferred: $pref_type"
log "TARGETS default: $default_string"
# match target with the preferred ones
combined_search_string=$(printf "%b%b" "$pref_type" "$default_string")
SAVEIFS=$IFS
IFS=$(printf "\n\b")
for f in $(printf "%b" "$combined_search_string"); do
for t in $(printf "%b" "$targets"); do
if [ "$f" = "$t" ]; then
first_found="$f"
break 2
fi
done
done
IFS=$SAVEIFS
if [ -n "$first_found" ]; then
log "TARGET found: $first_found"
if [ "$disabled" -eq 0 ]; then
# when clipboard data is text create a history entry
if [ "$first_found" = "text/plain" ] || [ "$first_found" = "text/plain;charset=utf-8" ] || [ "$first_found" = "$default_string" ]; then
clipboard=$(xclip -verbose -selection clipboard -t "$first_found" -o)
clipboard_hash=$(printf "%s" "$clipboard" | sha256sum | cut -d" " -f1)
if [ ! -f "$history_dir/$clipboard_hash" ]; then
history_current_size=$((history_current_size + 1))
log "History: created text entry"
fi
printf "%s" "$clipboard" >"$history_dir/$clipboard_hash"
fi
if [ "$history_current_size" -gt "$history_max_size" ]; then
# delete the oldest history entry
rm "$(find "$history_dir" -type f -printf '%T+ %p\n' | sort | head -1 | sed 's/[^ ]* //')"
history_current_size=$((history_current_size - 1))
log "History: full, entry deleted"
fi
if [ "$first_found" = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"" ]; then
first_found="UTF8_STRING"
# SAVEIFS=$IFS
# IFS=$(printf "\n\b")
# for t in $(printf "%b" "$targets"); do
# id=$(printf "%b" "$t" | grep -Eo 'application/x-libreoffice-internal-id-[0-9]+')
# if [ -n "$id" ]; then
# first_found="$id"
# log "TARGET LibreOffice found id: $id"
# break;
# fi
# done
# IFS=$SAVEIFS
# if [ -z "$first_found" ]; then
# first_found="UTF8_STRING"
# log "TARGET LibreOffice did not find id using UTF8_STRING"
# fi
fi
fi
# preserve clipboard contents
xclip -verbose -selection clipboard -t "$first_found" -o | xclip -verbose -selection clipboard -t "$first_found" -in
else
log "TARGET not found"
fi
fi
done