Inverse-only matches should not reorder the remaining results

Fix #1458
pull/1459/head
Junegunn Choi 6 years ago
parent 63c42b14f2
commit 5624a89231
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

@ -149,6 +149,7 @@ func Run(opts *Options, revision string) {
}
pattern := patternBuilder([]rune(*opts.Filter))
matcher.sort = pattern.sortable
found := false
if streamingFilter {

@ -230,5 +230,5 @@ func (m *Matcher) Reset(chunks []*Chunk, patternRunes []rune, cancel bool, final
} else {
event = reqRetry
}
m.reqBox.Set(event, MatchRequest{chunks, pattern, final, sort})
m.reqBox.Set(event, MatchRequest{chunks, pattern, final, sort && pattern.sortable})
}

@ -52,6 +52,7 @@ type Pattern struct {
forward bool
text []rune
termSets []termSet
sortable bool
cacheable bool
cacheKey string
delimiter Delimiter
@ -101,18 +102,27 @@ func BuildPattern(fuzzy bool, fuzzyAlgo algo.Algo, extended bool, caseMode Case,
}
caseSensitive := true
sortable := true
termSets := []termSet{}
if extended {
termSets = parseTerms(fuzzy, caseMode, normalize, asString)
// We should not sort the result if there are only inverse search terms
sortable = false
Loop:
for _, termSet := range termSets {
for idx, term := range termSet {
if !term.inv {
sortable = true
}
// If the query contains inverse search terms or OR operators,
// we cannot cache the search scope
if !cacheable || idx > 0 || term.inv || fuzzy && term.typ != termFuzzy || !fuzzy && term.typ != termExact {
cacheable = false
break Loop
if sortable {
// Can't break until we see at least one non-inverse term
break Loop
}
}
}
}
@ -134,6 +144,7 @@ func BuildPattern(fuzzy bool, fuzzyAlgo algo.Algo, extended bool, caseMode Case,
forward: forward,
text: []rune(asString),
termSets: termSets,
sortable: sortable,
cacheable: cacheable,
nth: nth,
delimiter: delimiter,

@ -1519,6 +1519,19 @@ class TestGoFZF < TestBase
assert_equal ['foo bar'], `#{FZF} -f'^foo\\ bar$' < #{tempname}`.lines.map(&:chomp)
assert_equal input.lines.count - 1, `#{FZF} -f'!^foo\\ bar$' < #{tempname}`.lines.count
end
def test_inverse_only_search_should_not_sort_the_result
# Filter
assert_equal(%w[aaaaa b ccc],
`printf '%s\n' aaaaa b ccc BAD | #{FZF} -f '!bad'`.lines.map(&:chomp))
# Interactive
tmux.send_keys(%[printf '%s\n' aaaaa b ccc BAD | #{FZF} -q '!bad'], :Enter)
tmux.until { |lines| lines.item_count == 4 && lines.match_count == 3 }
tmux.until { |lines| lines[-3] == '> aaaaa' }
tmux.until { |lines| lines[-4] == ' b' }
tmux.until { |lines| lines[-5] == ' ccc' }
end
end
module TestShell

Loading…
Cancel
Save