forked from peco/peco
-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.go
50 lines (45 loc) · 1.26 KB
/
filter.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
package peco
// Filter is responsible for the actual "grep" part of peco
type Filter struct {
*Ctx
jobs chan string
}
// Work is the actual work horse that that does the matching
// in a goroutine of its own. It wraps Matcher.Match().
func (f *Filter) Work(cancel chan struct{}, q HubReq) {
defer q.Done()
query := q.DataString()
if query == "" {
f.DrawMatches(nil)
return
}
f.SetCurrent(f.Matcher().Line(cancel, query, f.Buffer()))
f.SendStatusMsg("")
f.SelectionClear()
f.DrawMatches(nil)
}
// Loop keeps watching for incoming queries, and upon receiving
// a query, spawns a goroutine to do the heavy work. It also
// checks for previously running queries, so we can avoid
// running many goroutines doing the grep at the same time
func (f *Filter) Loop() {
defer f.ReleaseWaitGroup()
// previous holds a channel that can cancel the previous
// query. This is used when multiple queries come in succession
// and the previous query is discarded anyway
var previous chan struct{}
for {
select {
case <-f.LoopCh():
return
case q := <-f.QueryCh():
if previous != nil {
// Tell the previous query to stop
previous <- struct{}{}
}
previous = make(chan struct{}, 1)
f.SendStatusMsg("Running query...")
go f.Work(previous, q)
}
}
}