Make --select-1 and --exit-0 asynchronous

This commit is contained in:
Junegunn Choi 2015-02-18 00:08:17 +09:00
parent d760b790b3
commit e808151c28
3 changed files with 39 additions and 32 deletions

View File

@ -95,40 +95,25 @@ func Run(options *Options) {
}
matcher := NewMatcher(patternBuilder, opts.Sort > 0, eventBox)
// Defered-interactive / Non-interactive
// --select-1 | --exit-0 | --filter
if filtering := opts.Filter != nil; filtering || opts.Select1 || opts.Exit0 {
limit := 0
var patternString string
if filtering {
patternString = *opts.Filter
} else {
if opts.Select1 || opts.Exit0 {
limit = 1
}
patternString = opts.Query
}
pattern := patternBuilder([]rune(patternString))
// Filtering mode
if opts.Filter != nil {
pattern := patternBuilder([]rune(*opts.Filter))
eventBox.Unwatch(EvtReadNew)
eventBox.WaitFor(EvtReadFin)
snapshot, _ := chunkList.Snapshot()
merger, cancelled := matcher.scan(MatchRequest{
merger, _ := matcher.scan(MatchRequest{
chunks: snapshot,
pattern: pattern}, limit)
pattern: pattern})
if !cancelled && (filtering ||
opts.Exit0 && merger.Length() == 0 ||
opts.Select1 && merger.Length() == 1) {
if opts.PrintQuery {
fmt.Println(patternString)
}
for i := 0; i < merger.Length(); i++ {
fmt.Println(merger.Get(i).AsString())
}
os.Exit(0)
if opts.PrintQuery {
fmt.Println(*opts.Filter)
}
for i := 0; i < merger.Length(); i++ {
fmt.Println(merger.Get(i).AsString())
}
os.Exit(0)
}
// Synchronous search
@ -142,7 +127,11 @@ func Run(options *Options) {
// Terminal I/O
terminal := NewTerminal(opts, eventBox)
deferred := opts.Select1 || opts.Exit0
go terminal.Loop()
if !deferred {
terminal.startChan <- true
}
// Event coordination
reading := true
@ -176,6 +165,25 @@ func Run(options *Options) {
case EvtSearchFin:
switch val := value.(type) {
case *Merger:
if deferred {
count := val.Length()
if opts.Select1 && count > 1 || opts.Exit0 && !opts.Select1 && count > 0 {
deferred = false
terminal.startChan <- true
} else if !reading {
if opts.Exit0 && count == 0 || opts.Select1 && count == 1 {
if opts.PrintQuery {
fmt.Println(opts.Query)
}
for i := 0; i < count; i++ {
fmt.Println(val.Get(i).AsString())
}
os.Exit(0)
}
deferred = false
terminal.startChan <- true
}
}
terminal.UpdateList(val)
}
}

View File

@ -86,7 +86,7 @@ func (m *Matcher) Loop() {
}
if !foundCache {
merger, cancelled = m.scan(request, 0)
merger, cancelled = m.scan(request)
}
if !cancelled {
@ -121,7 +121,7 @@ type partialResult struct {
matches []*Item
}
func (m *Matcher) scan(request MatchRequest, limit int) (*Merger, bool) {
func (m *Matcher) scan(request MatchRequest) (*Merger, bool) {
startedAt := time.Now()
numChunks := len(request.chunks)
@ -175,10 +175,6 @@ func (m *Matcher) scan(request MatchRequest, limit int) (*Merger, bool) {
count++
matchCount += matchesInChunk
if limit > 0 && matchCount > limit {
return nil, wait() // For --select-1 and --exit-0
}
if count == numChunks {
break
}

View File

@ -40,6 +40,7 @@ type Terminal struct {
mutex sync.Mutex
initFunc func()
suppress bool
startChan chan bool
}
type selectedItem struct {
@ -99,6 +100,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
eventBox: eventBox,
mutex: sync.Mutex{},
suppress: true,
startChan: make(chan bool, 1),
initFunc: func() {
C.Init(opts.Color, opts.Color256, opts.Black, opts.Mouse)
}}
@ -446,6 +448,7 @@ func (t *Terminal) rubout(pattern string) {
// Loop is called to start Terminal I/O
func (t *Terminal) Loop() {
<-t.startChan
{ // Late initialization
t.mutex.Lock()
t.initFunc()