-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathdemon.go
106 lines (87 loc) · 2.17 KB
/
demon.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
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os/exec"
"time"
)
func write(history []string, histfile string) error {
histlog, err := json.Marshal(history)
if err != nil {
return err
}
err = ioutil.WriteFile(histfile, histlog, 0644)
if err != nil {
return err
}
return nil
}
func filter(history []string, text string) []string {
var (
found bool
idx int
)
for i, el := range history {
if el == text {
found = true
idx = i
break
}
}
if found {
// we know that idx can't be the last element, because
// we never get to call this function if that's the case
history = append(history[:idx], history[idx+1:]...)
}
return history
}
func listen(history []string, histfile string, persist bool, max int) error {
for {
t, err := exec.Command("wl-paste", []string{"-n", "-t", "text"}...).CombinedOutput()
if err != nil {
// wl-paste exits 1 if there's no selection (e.g., when running it at OS startup)
if string(t) != "No selection\n" {
log.Printf("Error running wl-paste (demon.52): %s", t)
}
time.Sleep(1 * time.Second)
continue
}
text := string(t)
if text == "" {
// there's nothing to select, so we sleep.
time.Sleep(1 * time.Second)
continue
}
l := len(history)
if l > 0 {
// wl-paste will always give back the last copied text
// (as long as the place we copied from is still running)
if history[l-1] == text {
time.Sleep(1 * time.Second)
continue
}
if l == max {
// we know that at any given time len(history) cannot be bigger than max,
// so it's enough to drop the first element
history = history[1:]
}
// remove duplicates
history = filter(history, text)
}
history = append(history, text)
// dump history to file so that other apps can query it
err = write(history, histfile)
if err != nil {
return fmt.Errorf("error writing history (demon.83): %s", err)
}
if persist {
// make the copy buffer available to all applications,
// even when the source has disappeared
if err := exec.Command("wl-copy", []string{"--", text}...).Run(); err != nil {
return fmt.Errorf("error running wl-copy (demon.91): %s", err)
}
}
}
}