-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
120 lines (97 loc) · 2.67 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"flag"
"fmt"
"log"
"os"
"reflect"
"runtime/debug"
"golang.design/x/clipboard"
"golang.design/x/hotkey"
"golang.design/x/hotkey/mainthread"
)
const usage = `Usage:
olaf [--version]
Options:
--version Print the version and exit.
At startup, olaf registers eight different hotkeys. Four of these hotkeys are
used to copy the contents of the system clipboard to a virtual clipboard, and
the other four are used to copy the contents of a virtual clipboard back into
the system clipboard.
The registered hotkeys are Ctrl+<H> and Alt+<H>, where <H> is the name of one
of the virtual clipboards. There are four virtual clipboards: u, i, o, and p.
You will usually want to run olaf as a background task, especially if you are
using the CLI. If you are using a bash-like shell, see the example.
Example:
$ olaf &`
var Version string
func main() {
flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) }
var versionFlag bool
flag.BoolVar(&versionFlag, "version", false, "print the version")
flag.Parse()
if versionFlag {
if Version != "" {
fmt.Println(Version)
return
}
if buildInfo, ok := debug.ReadBuildInfo(); ok {
fmt.Println(buildInfo.Main.Version)
return
}
fmt.Println("(unknown)")
return
}
mainthread.Init(run)
}
func run() {
const n int = 4
err := clipboard.Init()
if err != nil {
errorf("failed to initialize system clipboard: %v", err)
}
// We clean the clipboard formatting to avoid weird behaviors.
clipboard.Write(clipboard.FmtText, clipboard.Read(clipboard.FmtText))
keys := []hotkey.Key{hotkey.KeyU, hotkey.KeyI, hotkey.KeyO, hotkey.KeyP}
copyHotkeys, err := registerCopy(keys)
if err != nil {
errorf("failed to register copy hotkeys: %v", err)
}
pasteHotkeys, err := registerPaste(keys)
if err != nil {
errorf("failed to register paste hotkeys: %v", err)
}
var cases []reflect.SelectCase
for _, hk := range copyHotkeys {
cases = append(cases, reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(hk.Keydown()),
})
}
for _, hk := range pasteHotkeys {
cases = append(cases, reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(hk.Keydown()),
})
}
clipboards := make([]Clipboard, n)
for {
chosen, _, _ := reflect.Select(cases)
switch {
case chosen < n:
clipboards[chosen] = clipboard.Read(clipboard.FmtText)
default:
i := chosen - n
clipboard.Write(clipboard.FmtText, clipboards[i])
}
}
}
type Clipboard []byte
// l is a logger with no prefixes.
var l = log.New(os.Stderr, "", 0)
func printf(format string, v ...any) {
l.Printf("olaf: "+format, v...)
}
func errorf(format string, v ...any) {
l.Fatalf("olaf: error: "+format, v...)
}