diff --git a/fzf b/fzf index 4c69f1b..bcdc077 100755 --- a/fzf +++ b/fzf @@ -98,7 +98,7 @@ class FZF end while o = argv.shift case o - when '--version' then version + when '--version' then FZF.version when '-h', '--help' then usage 0 when '-m', '--multi' then @multi = true when '+m', '--no-multi' then @multi = false @@ -225,7 +225,7 @@ class FZF def filter_list list matches = matcher.match(list, @filter, '', '') if @sort && matches.length <= @sort - matches = sort_by_rank(matches) + matches = FZF.sort(matches) end matches.each { |m| puts m.first } end @@ -239,15 +239,34 @@ class FZF end end - def version - File.open(__FILE__, 'r') do |f| - f.each_line do |line| - if line =~ /Version: (.*)/ - $stdout.puts 'fzf ' << $1 - exit + class << self + def version + File.open(__FILE__, 'r') do |f| + f.each_line do |line| + if line =~ /Version: (.*)/ + $stdout.puts 'fzf ' << $1 + exit + end end end end + + def sort list + list.sort_by { |tuple| rank tuple } + end + + def rank tuple + line, offsets = tuple + matchlen = 0 + pe = 0 + offsets.sort.each do |pair| + b, e = pair + b = pe if pe > b + pe = e if e > pe + matchlen += e - b if e > b + end + [matchlen, line.length, line] + end end def usage x, message = nil @@ -519,21 +538,6 @@ class FZF C.attroff color(:chosen, true) if chosen end - def sort_by_rank list - list.sort_by { |tuple| - line, offsets = tuple - matchlen = 0 - pe = nil - offsets.sort.each do |pair| - b, e = pair - b = pe if pe && pe > b - pe = e - matchlen += e - b - end - [matchlen, line.length, line] - } - end - AFTER_1_9 = RUBY_VERSION.split('.').map { |e| e.rjust(3, '0') }.join >= '001009' if AFTER_1_9 @@ -725,7 +729,7 @@ class FZF next if skip matches = @sort ? found : found.reverse if !empty && @sort && matches.length <= @sort - matches = sort_by_rank(matches) + matches = FZF.sort(matches) end fcache[q] = matches end diff --git a/test/test_fzf.rb b/test/test_fzf.rb index ea2ecd9..fc30476 100644 --- a/test/test_fzf.rb +++ b/test/test_fzf.rb @@ -400,7 +400,7 @@ class TestFZF < MiniTest::Unit::TestCase ["0____1", [[0, 6]]], ["0_____1", [[0, 7]]], ["0______1", [[0, 8]]]], - FZF.new([]).sort_by_rank(matcher.match(list, '01', '', ''))) + FZF.sort(matcher.match(list, '01', '', ''))) assert_equal( [["01", [[0, 1], [1, 2]]], @@ -411,16 +411,19 @@ class TestFZF < MiniTest::Unit::TestCase ["____0_1", [[4, 5], [6, 7]]], ["0______1", [[0, 1], [7, 8]]], ["___01___", [[3, 4], [4, 5]]]], - FZF.new([]).sort_by_rank(xmatcher.match(list, '0 1', '', ''))) + FZF.sort(xmatcher.match(list, '0 1', '', ''))) assert_equal( - [["_01_", [[1, 3], [0, 4]]], - ["0____1", [[0, 6], [1, 3]]], - ["0_____1", [[0, 7], [1, 3]]], - ["0______1", [[0, 8], [1, 3]]], - ["___01___", [[3, 5], [0, 2]]], - ["____0_1", [[4, 7], [0, 2]]]], - FZF.new([]).sort_by_rank(xmatcher.match(list, '01 __', '', ''))) + [["_01_", [[1, 3], [0, 4]], [4, 4, "_01_"]], + ["___01___", [[3, 5], [0, 2]], [4, 8, "___01___"]], + ["____0_1", [[4, 7], [0, 2]], [5, 7, "____0_1"]], + ["0____1", [[0, 6], [1, 3]], [6, 6, "0____1"]], + ["0_____1", [[0, 7], [1, 3]], [7, 7, "0_____1"]], + ["0______1", [[0, 8], [1, 3]], [8, 8, "0______1"]]], + FZF.sort(xmatcher.match(list, '01 __', '', '')).map { |tuple| + tuple << FZF.rank(tuple) + } + ) end def test_extended_exact_mode @@ -647,5 +650,16 @@ class TestFZF < MiniTest::Unit::TestCase $stdout = STDOUT end end + + def test_ranking_overlap_match_regions + list = [ + '1 3 4 2', + '1 2 3 4' + ] + assert_equal [ + ['1 2 3 4', [[0, 13], [16, 22]]], + ['1 3 4 2', [[0, 24], [12, 17]]], + ], FZF.sort(FZF::ExtendedFuzzyMatcher.new(nil).match(list, '12 34', '', '')) + end end