diff options
author | Junegunn Choi <junegunn.c@gmail.com> | 2015-03-01 11:16:38 +0900 |
---|---|---|
committer | Junegunn Choi <junegunn.c@gmail.com> | 2015-03-01 11:16:38 +0900 |
commit | 94e8e6419f29c8a9a5998abca15e7aa70c7eabda (patch) | |
tree | ec93a17856a3762d0363194635bf384016b53b50 /src/core.go | |
parent | 4d2d18649c1740defed24ee67915062398d5a699 (diff) |
Make --filter non-blocking when --no-sort (#132)
When fzf works in filtering mode (--filter) and sorting is disabled
(--no-sort), there's no need to block until input is complete. This
commit makes fzf print the matches on-the-fly when the following
condition is met:
--filter FILTER --no-sort [--no-tac --no-sync]
or simply:
-f FILTER +s
This removes unnecessary delay in use cases like the following:
fzf -f xxx +s | head -5
However, in this case, fzf processes the input lines sequentially, so it
cannot utilize multiple cores, which makes it slightly slower than the
previous mode of execution where filtering is done in parallel after the
entire input is loaded. If the user is concerned about the performance
problem, one can add --sync option to re-enable buffering.
Diffstat (limited to 'src/core.go')
-rw-r--r-- | src/core.go | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/src/core.go b/src/core.go index ec4c5e8d..62190d08 100644 --- a/src/core.go +++ b/src/core.go @@ -85,8 +85,11 @@ func Run(options *Options) { } // Reader - reader := Reader{func(str string) { chunkList.Push(str) }, eventBox} - go reader.ReadSource() + streamingFilter := opts.Filter != nil && opts.Sort == 0 && !opts.Tac && !opts.Sync + if !streamingFilter { + reader := Reader{func(str string) { chunkList.Push(str) }, eventBox} + go reader.ReadSource() + } // Matcher patternBuilder := func(runes []rune) *Pattern { @@ -97,21 +100,32 @@ func Run(options *Options) { // Filtering mode if opts.Filter != nil { - pattern := patternBuilder([]rune(*opts.Filter)) - - eventBox.Unwatch(EvtReadNew) - eventBox.WaitFor(EvtReadFin) - - snapshot, _ := chunkList.Snapshot() - merger, _ := matcher.scan(MatchRequest{ - chunks: snapshot, - pattern: pattern}) - if opts.PrintQuery { fmt.Println(*opts.Filter) } - for i := 0; i < merger.Length(); i++ { - fmt.Println(merger.Get(i).AsString()) + + pattern := patternBuilder([]rune(*opts.Filter)) + + if streamingFilter { + reader := Reader{ + func(str string) { + item := chunkList.trans(&str, 0) + if pattern.MatchItem(item) { + fmt.Println(*item.text) + } + }, eventBox} + reader.ReadSource() + } else { + eventBox.Unwatch(EvtReadNew) + eventBox.WaitFor(EvtReadFin) + + snapshot, _ := chunkList.Snapshot() + merger, _ := matcher.scan(MatchRequest{ + chunks: snapshot, + pattern: pattern}) + for i := 0; i < merger.Length(); i++ { + fmt.Println(merger.Get(i).AsString()) + } } os.Exit(0) } |