From f5b034095a74ae88410bf3383c39b1e99c0f36a0 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Wed, 18 Feb 2015 00:51:44 +0900 Subject: [PATCH] Fix race condition in asynchronous -1 and -0 --- src/core.go | 6 +++--- src/matcher.go | 6 ++++-- src/merger.go | 2 ++ test/test_go.rb | 10 ++++++++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/core.go b/src/core.go index 71e3aa9..ea97b4e 100644 --- a/src/core.go +++ b/src/core.go @@ -149,11 +149,11 @@ func Run(options *Options) { reading = reading && evt == EvtReadNew snapshot, count := chunkList.Snapshot() terminal.UpdateCount(count, !reading) - matcher.Reset(snapshot, terminal.Input(), false) + matcher.Reset(snapshot, terminal.Input(), false, !reading) case EvtSearchNew: snapshot, _ := chunkList.Snapshot() - matcher.Reset(snapshot, terminal.Input(), true) + matcher.Reset(snapshot, terminal.Input(), true, !reading) delay = false case EvtSearchProgress: @@ -170,7 +170,7 @@ func Run(options *Options) { if opts.Select1 && count > 1 || opts.Exit0 && !opts.Select1 && count > 0 { deferred = false terminal.startChan <- true - } else if !reading { + } else if val.final { if opts.Exit0 && count == 0 || opts.Select1 && count == 1 { if opts.PrintQuery { fmt.Println(opts.Query) diff --git a/src/matcher.go b/src/matcher.go index 84130b2..bfe9d28 100644 --- a/src/matcher.go +++ b/src/matcher.go @@ -14,6 +14,7 @@ import ( type MatchRequest struct { chunks []*Chunk pattern *Pattern + final bool } // Matcher is responsible for performing search @@ -91,6 +92,7 @@ func (m *Matcher) Loop() { if !cancelled { m.mergerCache[patternString] = merger + merger.final = request.final m.eventBox.Set(EvtSearchFin, merger) } } @@ -197,7 +199,7 @@ func (m *Matcher) scan(request MatchRequest) (*Merger, bool) { } // Reset is called to interrupt/signal the ongoing search -func (m *Matcher) Reset(chunks []*Chunk, patternRunes []rune, cancel bool) { +func (m *Matcher) Reset(chunks []*Chunk, patternRunes []rune, cancel bool, final bool) { pattern := m.patternBuilder(patternRunes) var event util.EventType @@ -206,5 +208,5 @@ func (m *Matcher) Reset(chunks []*Chunk, patternRunes []rune, cancel bool) { } else { event = reqRetry } - m.reqBox.Set(event, MatchRequest{chunks, pattern}) + m.reqBox.Set(event, MatchRequest{chunks, pattern, final}) } diff --git a/src/merger.go b/src/merger.go index bd2158d..5bfc81d 100644 --- a/src/merger.go +++ b/src/merger.go @@ -12,6 +12,7 @@ type Merger struct { merged []*Item cursors []int sorted bool + final bool count int } @@ -22,6 +23,7 @@ func NewMerger(lists [][]*Item, sorted bool) *Merger { merged: []*Item{}, cursors: make([]int, len(lists)), sorted: sorted, + final: false, count: 0} for _, list := range mg.lists { diff --git a/test/test_go.rb b/test/test_go.rb index 70e531f..27c7b33 100644 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -290,6 +290,16 @@ class TestGoFZF < MiniTest::Unit::TestCase assert_equal ['555555'], readonce.split($/) end + def test_select_1_exit_0_fail + [:'0', :'1', [:'1', :'0']].each do |opt| + tmux.send_keys "seq 1 100 | #{fzf :print_query, :multi, :q, 5, *opt}", :Enter + tmux.until { |lines| lines.last =~ /^> 5/ } + tmux.send_keys :BTab, :BTab, :BTab, :Enter + tmux.until { |lines| lines[-1].include?(FIN) } + assert_equal ['5', '5', '15', '25'], readonce.split($/) + end + end + def test_query_unicode tmux.send_keys "(echo abc; echo 가나다) | #{fzf :query, '가다'}", :Enter tmux.until { |lines| lines.last.start_with? '>' }