Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Fix scoring to favor exact substring matches
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonwamboldt committed Apr 25, 2015
1 parent 12eaa82 commit 21e1861
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 3 deletions.
9 changes: 6 additions & 3 deletions spec/filter-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ rootPath = (segments...) ->

describe "filtering", ->
it "returns an array of the most accurate results", ->
candidates = ['Gruntfile','filter', 'bile', null, '', undefined]
expect(filter(candidates, 'file')).toEqual ['filter', 'Gruntfile']
candidates = ['Gruntfile', 'filter', 'bile', null, '', undefined]
expect(filter(candidates, 'file')).toEqual ['Gruntfile', 'filter']

describe "when the maxResults option is set", ->
it "limits the results to the result size", ->
candidates = ['Gruntfile', 'filter', 'bile']
expect(bestMatch(candidates, 'file')).toBe 'filter'
expect(bestMatch(candidates, 'file')).toBe 'Gruntfile'

describe "when the entries contains slashes", ->
it "weighs basename matches higher", ->
Expand Down Expand Up @@ -112,6 +112,9 @@ describe "filtering", ->
expect(bestMatch(['z_a_b', 'a_b'], 'ab')).toBe 'a_b'
expect(bestMatch(['a_b_c', 'c_a_b'], 'ab')).toBe 'a_b_c'

it "weights matches that are substring matches higher", ->
expect(bestMatch(['/a/b/c/install.txt', 'inst-all.txt'])).toBe '/a/b/c/install.txt'

describe "when the entries are of differing directory depths", ->
it "places exact matches first, even if they're deeper", ->
candidates = [
Expand Down
1 change: 1 addition & 0 deletions src/filter.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = (candidates, query, queryHasSlashes, {key, maxResults}={}) ->
score = scorer.score(string, query, queryHasSlashes)
unless queryHasSlashes
score = scorer.basenameScore(string, query, score)
score = scorer.substringScore(string, query, score)
scoredCandidates.push({candidate, score}) if score > 0

# Sort scores in descending order
Expand Down
1 change: 1 addition & 0 deletions src/fuzzaldrin.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports =
query = query.replace(SpaceRegex, '')
score = scorer.score(string, query)
score = scorer.basenameScore(string, query, score) unless queryHasSlashes
score = scorer.substringScore(string, query, score)
score

match: (string, query) ->
Expand Down
16 changes: 16 additions & 0 deletions src/scorer.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ exports.basenameScore = (string, query, score) ->
score *= depth * 0.01
score

exports.substringScore = (string, query, score) ->
# Return a near perfect score if the query is a substring match
substrIndex = string.indexOf(query)
substrIndexi = string.toLowerCase().indexOf(query.toLowerCase())

if substrIndex >= 0
return score + 1.155 if substrIndex == 0
return score + 1.145 if string[substrIndex - 1] == PathSeparator
return score + 1.135
else if substrIndexi >= 0
return score + 1.15 if substrIndexi == 0
return score + 1.14 if string[substrIndexi - 1] == PathSeparator
return score + 1.13

return score

exports.score = (string, query) ->
return 1 if string is query

Expand Down

0 comments on commit 21e1861

Please sign in to comment.