mirror of
https://github.com/atom/atom.git
synced 2026-01-28 16:28:09 -05:00
Merge pull request #987 from atom/ks-fuzzaldrin
Extract string score and fuzzy filter
This commit is contained in:
@@ -16,7 +16,6 @@ module.exports =
|
||||
Point: Point
|
||||
Range: Range
|
||||
Site: Site
|
||||
stringscore: require '../vendor/stringscore'
|
||||
|
||||
# The following classes can't be used from a Task handler and should therefore
|
||||
# only be exported when not running as a child node process
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"coffeestack": "0.6.0",
|
||||
"emissary": "0.6.0",
|
||||
"first-mate": "0.4.0",
|
||||
"fuzzaldrin": "0.1.0",
|
||||
"git-utils": "0.26.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-focused": "~0.15.0",
|
||||
@@ -71,7 +72,7 @@
|
||||
"metrics": "0.8.0",
|
||||
"package-generator": "0.12.0",
|
||||
"release-notes": "0.4.0",
|
||||
"settings-view": "0.28.0",
|
||||
"settings-view": "0.29.0",
|
||||
"snippets": "0.9.0",
|
||||
"spell-check": "0.7.0",
|
||||
"status-bar": "0.14.0",
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
stringScore = require '../vendor/stringscore'
|
||||
path = require 'path'
|
||||
|
||||
module.exports = (candidates, query, options={}) ->
|
||||
if query
|
||||
scoredCandidates = candidates.map (candidate) ->
|
||||
string = if options.key? then candidate[options.key] else candidate
|
||||
score = stringScore(string, query)
|
||||
|
||||
unless /\//.test(query)
|
||||
# Basename matches count for more.
|
||||
score += stringScore(path.basename(string), query)
|
||||
|
||||
# Shallow files are scored higher
|
||||
depth = Math.max(1, 10 - string.split('/').length - 1)
|
||||
score *= depth * 0.01
|
||||
|
||||
{ candidate, score }
|
||||
|
||||
scoredCandidates.sort (a, b) ->
|
||||
if a.score > b.score then -1
|
||||
else if a.score < b.score then 1
|
||||
else 0
|
||||
candidates = (scoredCandidate.candidate for scoredCandidate in scoredCandidates when scoredCandidate.score > 0)
|
||||
|
||||
candidates = candidates[0...options.maxResults] if options.maxResults?
|
||||
candidates
|
||||
@@ -1,6 +1,6 @@
|
||||
{$, View} = require './space-pen-extensions'
|
||||
Editor = require './editor'
|
||||
fuzzyFilter = require './fuzzy-filter'
|
||||
fuzzyFilter = require('fuzzaldrin').filter
|
||||
|
||||
# Public: Provides a widget for users to make a selection from a list of
|
||||
# choices.
|
||||
|
||||
118
vendor/stringscore.js
vendored
118
vendor/stringscore.js
vendored
@@ -1,118 +0,0 @@
|
||||
// MODIFIED BY NS/CJ - Don't extend the prototype of String
|
||||
// MODIFIED BY CJ - Remove start_of_string_bonus
|
||||
|
||||
/*!
|
||||
* string_score.js: String Scoring Algorithm 0.1.10
|
||||
*
|
||||
* http://joshaven.com/string_score
|
||||
* https://github.com/joshaven/string_score
|
||||
*
|
||||
* Copyright (C) 2009-2011 Joshaven Potter <yourtech@gmail.com>
|
||||
* Special thanks to all of the contributors listed here https://github.com/joshaven/string_score
|
||||
* MIT license: http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Date: Tue Mar 1 2011
|
||||
*/
|
||||
|
||||
/**
|
||||
* Scores a string against another string.
|
||||
* 'Hello World'.score('he'); //=> 0.5931818181818181
|
||||
* 'Hello World'.score('Hello'); //=> 0.7318181818181818
|
||||
*/
|
||||
module.exports = function(string, abbreviation, fuzziness) {
|
||||
// If the string is equal to the abbreviation, perfect match.
|
||||
if (string == abbreviation) {return 1;}
|
||||
// If it's not a perfect match and is empty return 0
|
||||
if (abbreviation == "") {return 0;}
|
||||
|
||||
var total_character_score = 0,
|
||||
abbreviation_length = abbreviation.length,
|
||||
string_length = string.length,
|
||||
start_of_string_bonus,
|
||||
abbreviation_score,
|
||||
fuzzies=1,
|
||||
final_score;
|
||||
|
||||
// Walk through abbreviation and add up scores.
|
||||
for (var i = 0,
|
||||
character_score/* = 0*/,
|
||||
index_in_string/* = 0*/,
|
||||
c/* = ''*/,
|
||||
index_c_lowercase/* = 0*/,
|
||||
index_c_uppercase/* = 0*/,
|
||||
min_index/* = 0*/;
|
||||
i < abbreviation_length;
|
||||
++i) {
|
||||
|
||||
// Find the first case-insensitive match of a character.
|
||||
c = abbreviation.charAt(i);
|
||||
|
||||
index_c_lowercase = string.indexOf(c.toLowerCase());
|
||||
index_c_uppercase = string.indexOf(c.toUpperCase());
|
||||
min_index = Math.min(index_c_lowercase, index_c_uppercase);
|
||||
index_in_string = (min_index > -1) ? min_index : Math.max(index_c_lowercase, index_c_uppercase);
|
||||
|
||||
if (index_in_string === -1) {
|
||||
if (fuzziness) {
|
||||
fuzzies += 1-fuzziness;
|
||||
continue;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
character_score = 0.1;
|
||||
}
|
||||
|
||||
// Set base score for matching 'c'.
|
||||
|
||||
// Same case bonus.
|
||||
if (string[index_in_string] === c) {
|
||||
character_score += 0.1;
|
||||
}
|
||||
|
||||
// Consecutive letter & start-of-string Bonus
|
||||
if (index_in_string === 0) {
|
||||
// Increase the score when matching first character of the remainder of the string
|
||||
character_score += 0.6;
|
||||
if (i === 0) {
|
||||
// If match is the first character of the string
|
||||
// & the first character of abbreviation, add a
|
||||
// start-of-string match bonus.
|
||||
// start_of_string_bonus = 1 //true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Acronym Bonus
|
||||
// Weighing Logic: Typing the first character of an acronym is as if you
|
||||
// preceded it with two perfect character matches.
|
||||
if (string.charAt(index_in_string - 1) === ' ') {
|
||||
character_score += 0.8; // * Math.min(index_in_string, 5); // Cap bonus at 0.4 * 5
|
||||
}
|
||||
}
|
||||
|
||||
// Left trim the already matched part of the string
|
||||
// (forces sequential matching).
|
||||
string = string.substring(index_in_string + 1, string_length);
|
||||
|
||||
total_character_score += character_score;
|
||||
} // end of for loop
|
||||
|
||||
// Uncomment to weigh smaller words higher.
|
||||
// return total_character_score / string_length;
|
||||
|
||||
abbreviation_score = total_character_score / abbreviation_length;
|
||||
//percentage_of_matched_string = abbreviation_length / string_length;
|
||||
//word_score = abbreviation_score * percentage_of_matched_string;
|
||||
|
||||
// Reduce penalty for longer strings.
|
||||
//final_score = (word_score + abbreviation_score) / 2;
|
||||
final_score = ((abbreviation_score * (abbreviation_length / string_length)) + abbreviation_score) / 2;
|
||||
|
||||
final_score = final_score / fuzzies;
|
||||
|
||||
if (start_of_string_bonus && (final_score + 0.15 < 1)) {
|
||||
final_score += 0.15;
|
||||
}
|
||||
|
||||
return final_score;
|
||||
};
|
||||
Reference in New Issue
Block a user