1//go:build linux
2
3package tui
4
5import (
6 "context"
7 "fmt"
8 "os"
9)
10
11// ReadClipboardText reads plain text from a Wayland or X11 clipboard. The
12// small command-line clients are used to preserve zut's CGO-free build.
13func ReadClipboardText() (string, bool, error) {
14 var commands []clipboardTextCommand
15 if os.Getenv("WAYLAND_DISPLAY") != "" {
16 commands = append(commands, clipboardTextCommand{name: "wl-paste", args: []string{"--no-newline", "--type", "text"}})
17 }
18 if os.Getenv("DISPLAY") != "" {
19 commands = append(commands,
20 clipboardTextCommand{name: "xclip", args: []string{"-selection", "clipboard", "-out"}},
21 clipboardTextCommand{name: "xsel", args: []string{"--clipboard", "--output"}},
22 )
23 }
24 // Environment forwarding through multiplexers is not always reliable.
25 // Try every backend if no display variable made a preferred list.
26 if len(commands) == 0 {
27 commands = []clipboardTextCommand{
28 {name: "wl-paste", args: []string{"--no-newline", "--type", "text"}},
29 {name: "xclip", args: []string{"-selection", "clipboard", "-out"}},
30 {name: "xsel", args: []string{"--clipboard", "--output"}},
31 }
32 }
33 text, ok, err := readClipboardTextCommands(commands...)
34 if err == errClipboardCommandUnavailable {
35 return "", false, fmt.Errorf("text clipboard unavailable: install wl-clipboard, xclip, or xsel, or use the terminal paste shortcut")
36 }
37 if err != nil {
38 return "", false, fmt.Errorf("read text clipboard: %w", err)
39 }
40 return text, ok, nil
41}
42
43// WriteClipboardText writes plain text to a Wayland or X11 clipboard. Small
44// command-line clients keep zut's build CGO-free.
45func WriteClipboardText(ctx context.Context, text string) error {
46 var commands []clipboardTextCommand
47 if os.Getenv("WAYLAND_DISPLAY") != "" {
48 commands = append(commands, clipboardTextCommand{name: "wl-copy", args: []string{"--type", "text/plain"}})
49 }
50 if os.Getenv("DISPLAY") != "" {
51 commands = append(commands,
52 clipboardTextCommand{name: "xclip", args: []string{"-selection", "clipboard", "-in"}},
53 clipboardTextCommand{name: "xsel", args: []string{"--clipboard", "--input"}},
54 )
55 }
56 if len(commands) == 0 {
57 commands = []clipboardTextCommand{
58 {name: "wl-copy", args: []string{"--type", "text/plain"}},
59 {name: "xclip", args: []string{"-selection", "clipboard", "-in"}},
60 {name: "xsel", args: []string{"--clipboard", "--input"}},
61 }
62 }
63 if err := writeClipboardTextCommands(ctx, text, commands...); err != nil {
64 if err == errClipboardCommandUnavailable {
65 return fmt.Errorf("text clipboard unavailable: install wl-clipboard, xclip, or xsel")
66 }
67 return fmt.Errorf("write text clipboard: %w", err)
68 }
69 return nil
70}