client: actually write incoming messages to the OS clipboard
The MVP only printed to stdout. Now the listener calls clipboard.WriteAll on every received message, except when the message originated from itself (to avoid clobbering local edits with our own prior send). Adds: - github.com/atotto/clipboard (cross-platform: Win/macOS/Linux) - -no-clipboard flag for stdout-only mode - "→ clipboard updated" trace line so the user can confirm the write Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// tether-client: connects to a tether-server, prints messages to stdout.
|
// tether-client: connects to a tether-server, writes incoming messages
|
||||||
// MVP — does not yet touch the OS clipboard.
|
// to the OS clipboard and prints them to stdout.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -14,6 +14,13 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/atotto/clipboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
noClipboard bool
|
||||||
|
myLabel string
|
||||||
)
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
@@ -26,13 +33,20 @@ func main() {
|
|||||||
server := flag.String("server", "http://localhost:8765", "tether-server base URL")
|
server := flag.String("server", "http://localhost:8765", "tether-server base URL")
|
||||||
label := flag.String("label", "linux-client", "X-Tether-Client label")
|
label := flag.String("label", "linux-client", "X-Tether-Client label")
|
||||||
sendText := flag.String("send", "", "send this text and exit (otherwise listen)")
|
sendText := flag.String("send", "", "send this text and exit (otherwise listen)")
|
||||||
|
flag.BoolVar(&noClipboard, "no-clipboard", false, "don't write incoming messages to the OS clipboard")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
myLabel = *label
|
||||||
|
|
||||||
if *sendText != "" {
|
if *sendText != "" {
|
||||||
send(*server, *label, *sendText)
|
send(*server, *label, *sendText)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !noClipboard && clipboard.Unsupported {
|
||||||
|
fmt.Fprintln(os.Stderr, "tether-client: OS clipboard unsupported on this platform; falling back to stdout-only")
|
||||||
|
noClipboard = true
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if err := listen(*server, *label); err != nil {
|
if err := listen(*server, *label); err != nil {
|
||||||
log.Printf("stream error: %v — reconnecting in 3s", err)
|
log.Printf("stream error: %v — reconnecting in 3s", err)
|
||||||
@@ -85,6 +99,14 @@ func listen(server, label string) error {
|
|||||||
if err := json.Unmarshal([]byte(data), &m); err == nil {
|
if err := json.Unmarshal([]byte(data), &m); err == nil {
|
||||||
ts := time.UnixMilli(m.TS).Format("15:04:05")
|
ts := time.UnixMilli(m.TS).Format("15:04:05")
|
||||||
fmt.Printf("\n────── %s from %s ──────\n%s\n", ts, m.Source, m.Text)
|
fmt.Printf("\n────── %s from %s ──────\n%s\n", ts, m.Source, m.Text)
|
||||||
|
// Don't echo our own message back into our own clipboard
|
||||||
|
if !noClipboard && m.Source != myLabel {
|
||||||
|
if err := clipboard.WriteAll(m.Text); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, " ! clipboard write error: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintln(os.Stderr, " → clipboard updated")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ev, data = "", ""
|
ev, data = "", ""
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -1,3 +1,5 @@
|
|||||||
module github.com/pecord/tether
|
module github.com/pecord/tether
|
||||||
|
|
||||||
go 1.22
|
go 1.22
|
||||||
|
|
||||||
|
require github.com/atotto/clipboard v0.1.4
|
||||||
|
|||||||
Reference in New Issue
Block a user