]> git.lizzy.rs Git - micro.git/blob - internal/clipboard/clipboard.go
Merge
[micro.git] / internal / clipboard / clipboard.go
1 package clipboard
2
3 import (
4         "errors"
5
6         "github.com/zyedidia/clipboard"
7 )
8
9 type Method int
10
11 const (
12         // External relies on external tools for accessing the clipboard
13         // These include xclip, xsel, wl-clipboard for linux, pbcopy/pbpaste on Mac,
14         // and Syscalls on Windows.
15         External Method = iota
16         // Terminal uses the terminal to manage the clipboard via OSC 52. Many
17         // terminals do not support OSC 52, in which case this method won't work.
18         Terminal
19         // Internal just manages the clipboard with an internal buffer and doesn't
20         // attempt to interface with the system clipboard
21         Internal
22 )
23
24 // CurrentMethod is the method used to store clipboard information
25 var CurrentMethod Method = Internal
26
27 // A Register is a buffer used to store text. The system clipboard has the 'clipboard'
28 // and 'primary' (linux-only) registers, but other registers may be used internal to micro.
29 type Register int
30
31 const (
32         // ClipboardReg is the main system clipboard
33         ClipboardReg Register = -1
34         // PrimaryReg is the system primary clipboard (linux only)
35         PrimaryReg = -2
36 )
37
38 // Initialize attempts to initialize the clipboard using the given method
39 func Initialize(m Method) error {
40         var err error
41         switch m {
42         case External:
43                 err = clipboard.Initialize()
44         }
45         CurrentMethod = Internal
46         return err
47 }
48
49 // SetMethod changes the clipboard access method
50 func SetMethod(m string) Method {
51         switch m {
52         case "internal":
53                 CurrentMethod = Internal
54         case "external":
55                 CurrentMethod = External
56         case "terminal":
57                 CurrentMethod = Terminal
58         }
59         return CurrentMethod
60 }
61
62 // Read reads from a clipboard register
63 func Read(r Register) (string, error) {
64         return read(r, CurrentMethod)
65 }
66
67 // Write writes text to a clipboard register
68 func Write(text string, r Register) error {
69         return write(text, r, CurrentMethod)
70 }
71
72 // ReadMulti reads text from a clipboard register for a certain multi-cursor
73 func ReadMulti(r Register, num, ncursors int) (string, error) {
74         clip, err := Read(r)
75         if err != nil {
76                 return "", err
77         }
78         if ValidMulti(r, clip, ncursors) {
79                 return multi.getText(r, num), nil
80         }
81         return clip, nil
82 }
83
84 // WriteMulti writes text to a clipboard register for a certain multi-cursor
85 func WriteMulti(text string, r Register, num int, ncursors int) error {
86         return writeMulti(text, r, num, ncursors, CurrentMethod)
87 }
88
89 // ValidMulti checks if the internal multi-clipboard is valid and up-to-date
90 // with the system clipboard
91 func ValidMulti(r Register, clip string, ncursors int) bool {
92         return multi.isValid(r, clip, ncursors)
93 }
94
95 func writeMulti(text string, r Register, num int, ncursors int, m Method) error {
96         multi.writeText(text, r, num, ncursors)
97         return write(multi.getAllText(r), r, m)
98 }
99
100 func read(r Register, m Method) (string, error) {
101         switch m {
102         case External:
103                 switch r {
104                 case ClipboardReg:
105                         return clipboard.ReadAll("clipboard")
106                 case PrimaryReg:
107                         return clipboard.ReadAll("primary")
108                 default:
109                         return internal.read(r), nil
110                 }
111         case Internal:
112                 return internal.read(r), nil
113         case Terminal:
114                 switch r {
115                 case ClipboardReg:
116                         // terminal paste works by sending an esc sequence to the
117                         // terminal to trigger a paste event
118                         return terminal.read("clipboard")
119                 case PrimaryReg:
120                         return terminal.read("primary")
121                 default:
122                         return internal.read(r), nil
123                 }
124         }
125         return "", errors.New("Invalid clipboard method")
126 }
127
128 func write(text string, r Register, m Method) error {
129         switch m {
130         case External:
131                 switch r {
132                 case ClipboardReg:
133                         return clipboard.WriteAll(text, "clipboard")
134                 case PrimaryReg:
135                         return clipboard.WriteAll(text, "primary")
136                 default:
137                         internal.write(text, r)
138                 }
139         case Internal:
140                 internal.write(text, r)
141         case Terminal:
142                 switch r {
143                 case ClipboardReg:
144                         return terminal.write(text, "c")
145                 case PrimaryReg:
146                         return terminal.write(text, "p")
147                 default:
148                         internal.write(text, r)
149                 }
150         }
151         return nil
152 }