Make dashboard updateable
This commit is contained in:
84
system_clipboard.go
Normal file
84
system_clipboard.go
Normal file
@@ -0,0 +1,84 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user