Files
diple/system_clipboard.go
2026-07-28 14:54:19 +02:00

85 lines
2.1 KiB
Go

package main
import (
"bytes"
"fmt"
"os/exec"
"runtime"
)
type textClipboard interface {
ReadText() (string, error)
WriteText(string) error
}
type systemTextClipboard struct{}
func (systemTextClipboard) ReadText() (string, error) {
command, args, err := clipboardCommand(false)
if err != nil {
return "", err
}
output, err := exec.Command(command, args...).Output()
if err != nil {
return "", fmt.Errorf("read system clipboard: %w", err)
}
return string(output), nil
}
func (systemTextClipboard) WriteText(value string) error {
command, args, err := clipboardCommand(true)
if err != nil {
return err
}
process := exec.Command(command, args...)
process.Stdin = bytes.NewBufferString(value)
if output, err := process.CombinedOutput(); err != nil {
if len(output) > 0 {
return fmt.Errorf("write system clipboard: %w: %s", err, bytes.TrimSpace(output))
}
return fmt.Errorf("write system clipboard: %w", err)
}
return nil
}
func clipboardCommand(write bool) (string, []string, error) {
switch runtime.GOOS {
case "darwin":
if write {
return "pbcopy", nil, nil
}
return "pbpaste", nil, nil
case "windows":
script := "Get-Clipboard -Raw"
if write {
script = "$input | Set-Clipboard"
}
return "powershell.exe", []string{"-NoProfile", "-NonInteractive", "-Command", script}, nil
default:
type candidate struct {
command string
write []string
read []string
}
candidates := []candidate{
{command: "wl-copy", read: []string{"-n"}, write: nil},
{command: "xclip", read: []string{"-selection", "clipboard", "-o"}, write: []string{"-selection", "clipboard", "-i"}},
{command: "xsel", read: []string{"--clipboard", "--output"}, write: []string{"--clipboard", "--input"}},
}
for _, candidate := range candidates {
command := candidate.command
args := candidate.read
if candidate.command == "wl-copy" && !write {
command = "wl-paste"
}
if write {
args = candidate.write
}
if _, err := exec.LookPath(command); err == nil {
return command, args, nil
}
}
return "", nil, fmt.Errorf("system clipboard unavailable: install wl-clipboard, xclip, or xsel")
}
}