-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·216 lines (184 loc) · 8.18 KB
/
install.sh
File metadata and controls
executable file
·216 lines (184 loc) · 8.18 KB
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#!/usr/bin/env bash
# flashpaste installer — symlinks scripts into ~/.local/bin and prints
# the config snippets you need to drop into tmux + kitty.
set -euo pipefail
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
BIN_SRC="$REPO_DIR/bin"
BIN_DST="$HOME/.local/bin"
SYSTEMD_DST="$HOME/.config/systemd/user"
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
RED='\033[1;31m'
RESET='\033[0m'
say() { printf "${GREEN}==>${RESET} %s\n" "$*"; }
warn() { printf "${YELLOW}warn:${RESET} %s\n" "$*"; }
die() { printf "${RED}error:${RESET} %s\n" "$*" >&2; exit 1; }
# ── deps ────────────────────────────────────────────────────────────
for cmd in tmux xclip wl-copy wl-paste ydotool; do
command -v "$cmd" >/dev/null 2>&1 || warn "missing dep: $cmd (install via your package manager)"
done
# ── ~/.local/bin/ symlinks ──────────────────────────────────────────
mkdir -p "$BIN_DST"
for script in tmux-paste-dispatch.sh clipboard-set.sh clipboard-janitor.sh \
get-clipboard-text.sh clip-pipeline-log.sh screenshot-to-clipboard \
flashpaste-screenshot-preload.sh flashpaste-doctor.sh \
flashpaste-trace.sh flashpaste-logs.sh \
flashpaste-capture-clip; do
src="$BIN_SRC/$script"
# Drop the .sh suffix on the destination for the user-facing log viewer
# so `flashpaste-logs` is what shows up on $PATH (matches the muscle
# memory of `flashpaste-trigger`, `flashpaste-doctor`, etc.). Other
# scripts in this loop keep their suffix because they're called
# internally by name.
case "$script" in
flashpaste-logs.sh) dst="$BIN_DST/flashpaste-logs" ;;
*) dst="$BIN_DST/$script" ;;
esac
if [ -e "$dst" ] && [ ! -L "$dst" ]; then
warn "$dst already exists as a real file; backing up to $dst.flashpaste-bak"
mv "$dst" "$dst.flashpaste-bak"
fi
ln -sf "$src" "$dst"
say "symlinked $script -> $src"
if [ "$script" = "tmux-paste-dispatch.sh" ]; then
ln -sf "$src" "$BIN_DST/tmux-paste-dispatch"
say "symlinked tmux-paste-dispatch -> $src"
fi
done
# wl-paste shim is special: replaces any existing symlink to /usr/bin/wl-paste.
WLP="$BIN_DST/wl-paste"
if [ -e "$WLP" ] && [ ! -L "$WLP" ]; then
warn "$WLP exists as a real file; backing up to $WLP.flashpaste-bak"
mv "$WLP" "$WLP.flashpaste-bak"
fi
ln -sf "$BIN_SRC/wl-paste" "$WLP"
say "symlinked wl-paste shim (overrides /usr/bin/wl-paste via PATH order)"
RS_BIN_SRC=""
if [ -d "$REPO_DIR/rs/target/release" ]; then
RS_BIN_SRC="$REPO_DIR/rs/target/release"
elif [ -d "$REPO_DIR/rs/target/debug" ]; then
RS_BIN_SRC="$REPO_DIR/rs/target/debug"
fi
if [ -n "$RS_BIN_SRC" ]; then
rs_found=0
for bin in flashpaste flashpasted flashpaste-dispatch flashpaste-trigger \
flashpaste-shoot flashpaste-mcp flashpaste-overlayd flashpaste-overlay; do
if [ -x "$RS_BIN_SRC/$bin" ]; then
ln -sf "$RS_BIN_SRC/$bin" "$BIN_DST/$bin"
say "symlinked $bin -> $RS_BIN_SRC/$bin"
rs_found=1
fi
done
[ "$rs_found" -eq 1 ] || warn "no executable Rust binaries found under $RS_BIN_SRC"
else
warn "Rust binaries not found under rs/target/{release,debug}; daemon/overlay services will be installed but not started"
fi
# paste_image.sh lives at $HOME (referenced by absolute path from kitty.conf).
ln -sf "$BIN_SRC/paste_image.sh" "$HOME/paste_image.sh"
say "symlinked ~/paste_image.sh -> $BIN_SRC/paste_image.sh"
# ── PATH order check ────────────────────────────────────────────────
if ! echo ":$PATH:" | grep -q ":$BIN_DST:"; then
warn "$BIN_DST not in PATH — add this to your ~/.bashrc or ~/.zshrc:"
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
elif ! command -v wl-paste | grep -q "^$BIN_DST"; then
warn "$BIN_DST is in PATH but /usr/bin precedes it — wl-paste shim won't activate."
fi
# ── desktop entries (hide phantom dock icons) ──────────────────────
APPS_DST="$HOME/.local/share/applications"
mkdir -p "$APPS_DST"
ln -sf "$REPO_DIR/share/applications/wl-clipboard.desktop" "$APPS_DST/wl-clipboard.desktop"
say "installed wl-clipboard.desktop (hides phantom dock entry)"
# ── systemd user services ──────────────────────────────────────────
mkdir -p "$SYSTEMD_DST"
cat > "$SYSTEMD_DST/clipboard-janitor.service" <<EOF
[Unit]
Description=Reap stuck wl-paste / wl-copy daemons (flashpaste)
[Service]
Type=simple
ExecStart=%h/.local/bin/clipboard-janitor.sh
Restart=on-failure
RestartSec=3
[Install]
WantedBy=default.target
EOF
say "wrote $SYSTEMD_DST/clipboard-janitor.service"
# Screenshot watcher — fires the preload script when ~/Pictures/Screenshots/
# changes, so xclip is hot before the user even reaches for paste.
cat > "$SYSTEMD_DST/flashpaste-screenshot-watcher.path" <<'EOF'
[Unit]
Description=Watch ~/Pictures/Screenshots/ for new PNGs (flashpaste)
[Path]
PathChanged=%h/Pictures/Screenshots
Unit=flashpaste-screenshot-watcher.service
[Install]
WantedBy=default.target
EOF
cat > "$SYSTEMD_DST/flashpaste-screenshot-watcher.service" <<'EOF'
[Unit]
Description=Pre-load fresh screenshot into xclip (flashpaste)
[Service]
Type=oneshot
ExecStart=%h/.local/bin/flashpaste-screenshot-preload.sh
EOF
say "wrote flashpaste-screenshot-watcher.{path,service}"
cat > "$SYSTEMD_DST/flashpaste-overlayd.service" <<'EOF'
[Unit]
Description=flashpaste overlay daemon (agent-driven screen annotations)
Documentation=https://github.com/NagyVikt/flashpaste
After=graphical-session.target
PartOf=graphical-session.target
[Service]
Type=notify
ExecStart=%h/.local/bin/flashpaste-overlayd
Restart=on-failure
RestartSec=2
Environment=RUST_LOG=info
[Install]
WantedBy=default.target
EOF
say "wrote flashpaste-overlayd.service"
# ydotoold socket-path patch (Ubuntu 24.04 0.1.8 bug)
if systemctl --user list-unit-files ydotoold.service >/dev/null 2>&1; then
cat > "$SYSTEMD_DST/ydotoold.service.d/flashpaste-socket.conf" 2>/dev/null <<EOF || true
[Service]
ExecStartPost=/bin/ln -sf /tmp/.ydotool_socket %t/.ydotool_socket
ExecStopPost=/bin/rm -f %t/.ydotool_socket
EOF
mkdir -p "$SYSTEMD_DST/ydotoold.service.d"
cat > "$SYSTEMD_DST/ydotoold.service.d/flashpaste-socket.conf" <<EOF
[Service]
ExecStartPost=/bin/ln -sf /tmp/.ydotool_socket %t/.ydotool_socket
ExecStopPost=/bin/rm -f %t/.ydotool_socket
EOF
say "patched ydotoold.service with socket-path symlink (Ubuntu 24.04 fix)"
fi
systemctl --user daemon-reload
systemctl --user enable --now clipboard-janitor.service
systemctl --user enable --now flashpaste-screenshot-watcher.path
if [ -x "$BIN_DST/flashpaste-overlayd" ]; then
if systemctl --user enable --now flashpaste-overlayd.service; then
say "enabled flashpaste-overlayd"
else
warn "flashpaste-overlayd.service could not be started; run flashpaste-doctor for details"
fi
else
warn "skipping flashpaste-overlayd.service start because $BIN_DST/flashpaste-overlayd is missing"
fi
say "enabled clipboard-janitor + flashpaste-screenshot-watcher"
# ── config snippets ─────────────────────────────────────────────────
cat <<'EOF'
────────────────────────────────────────────────────────────────────
flashpaste installed. Now append these to your dotfiles:
examples/tmux.conf.snippet → ~/.tmux.conf
examples/kitty.conf.snippet → ~/.config/kitty/kitty.conf
Then reload:
tmux source-file ~/.tmux.conf
# restart kitty
Test:
1. Press PrtScr to take a screenshot.
2. Right-click in any tmux pane → Paste.
3. Image should attach in <120 ms.
Watch the timeline live:
tail -F ~/.local/state/tmux-paste.log | grep T+
────────────────────────────────────────────────────────────────────
EOF