Skip to content

Commit b255555

Browse files
committed
Adjust scoring system
1 parent d20d70b commit b255555

1 file changed

Lines changed: 35 additions & 45 deletions

File tree

lib/rdoc/generator/template/aliki/js/search_ranker.js

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* 3. Match types:
88
* - Namespace queries (::) and method queries (# or .) match against full_name
99
* - Regular queries match against unqualified name
10-
* - Prefix match (1000) > substring match (100) > fuzzy match (10)
10+
* - Prefix (10000) > substring (5000) > fuzzy (1000)
1111
* 4. First character determines type priority:
1212
* - Starts with lowercase: methods first
1313
* - Starts with uppercase: classes/modules/constants first
@@ -22,6 +22,25 @@
2222
var MAX_RESULTS = 30;
2323
var MIN_QUERY_LENGTH = 1;
2424

25+
/*
26+
* Scoring constants - organized in tiers where each tier dominates lower tiers.
27+
* This ensures match type always beats type priority, etc.
28+
*
29+
* Tier 0: Exact matches (immediate return)
30+
* Tier 1: Match type (prefix > substring > fuzzy)
31+
* Tier 2: Exact name bonus
32+
* Tier 3: Type priority (method vs class based on query case)
33+
* Tier 4: Minor bonuses (top-level, class method, name length)
34+
*/
35+
var SCORE_EXACT_FULL_NAME = 1000000; // Tier 0: Query exactly matches full_name
36+
var SCORE_MATCH_PREFIX = 10000; // Tier 1: Query is prefix of name
37+
var SCORE_MATCH_SUBSTRING = 5000; // Tier 1: Query is substring of name
38+
var SCORE_MATCH_FUZZY = 1000; // Tier 1: Query chars appear in order
39+
var SCORE_EXACT_NAME = 500; // Tier 2: Name exactly equals query
40+
var SCORE_TYPE_PRIORITY = 100; // Tier 3: Preferred type (method/class)
41+
var SCORE_TOP_LEVEL = 50; // Tier 4: Top-level over namespaced
42+
var SCORE_CLASS_METHOD = 10; // Tier 4: Class method over instance method
43+
2544
/**
2645
* Check if all characters in query appear in order in target
2746
* e.g., "addalias" fuzzy matches "add_foo_alias"
@@ -112,61 +131,32 @@ function computeScore(entry, q) {
112131

113132
// Exact full_name match (e.g., "Array#filter" matches Array#filter)
114133
if (q.matchesFullName && fullNameLower === q.normalized) {
115-
return 1000000;
134+
return SCORE_EXACT_FULL_NAME;
116135
}
117136

118137
var matchScore = 0;
119-
120-
if (q.matchesFullName) {
121-
// For namespace queries like "Foo::Bar" or method queries like "Array#filter",
122-
// match against full_name
123-
if (fullNameLower.startsWith(q.normalized)) {
124-
matchScore = 1000; // Prefix (e.g., "Arr" matches "Array")
125-
} else if (fullNameLower.includes(q.normalized)) {
126-
matchScore = 100; // Substring (e.g., "ray" matches "Array")
127-
} else if (fuzzyMatch(fullNameLower, q.normalized)) {
128-
matchScore = 10; // Fuzzy (e.g., "addalias" matches "add_foo_alias")
129-
} else {
130-
return null;
131-
}
138+
var target = q.matchesFullName ? fullNameLower : nameLower;
139+
140+
if (target.startsWith(q.normalized)) {
141+
matchScore = SCORE_MATCH_PREFIX; // Prefix (e.g., "Arr" matches "Array")
142+
} else if (target.includes(q.normalized)) {
143+
matchScore = SCORE_MATCH_SUBSTRING; // Substring (e.g., "ray" matches "Array")
144+
} else if (fuzzyMatch(target, q.normalized)) {
145+
matchScore = SCORE_MATCH_FUZZY; // Fuzzy (e.g., "addalias" matches "add_foo_alias")
132146
} else {
133-
// For regular queries, match against unqualified name
134-
if (nameLower.startsWith(q.normalized)) {
135-
matchScore = 1000; // Prefix
136-
} else if (nameLower.includes(q.normalized)) {
137-
matchScore = 100; // Substring
138-
} else if (fuzzyMatch(nameLower, q.normalized)) {
139-
matchScore = 10; // Fuzzy
140-
} else {
141-
return null;
142-
}
147+
return null;
143148
}
144149

145150
var score = matchScore;
146151
var isMethod = (type === 'instance_method' || type === 'class_method');
147152

148-
if (q.prioritizeMethod) {
149-
if (isMethod) score += 10000;
150-
} else {
151-
if (!isMethod) score += 10000;
152-
}
153-
154-
// Class method > instance method
155-
if (type === 'class_method') {
156-
score += 500;
157-
}
158-
159-
// Top-level (Hash) > namespaced (Foo::Hash)
160-
if (name === fullName) {
161-
score += 5000;
162-
}
163-
164-
// Exact name match (e.g., "Hash" matches Hash over Hashable)
165-
if (nameLower === q.normalized) {
166-
score += 50000;
153+
if (q.prioritizeMethod ? isMethod : !isMethod) {
154+
score += SCORE_TYPE_PRIORITY;
167155
}
168156

169-
// Shorter name is better (subtract name length)
157+
if (type === 'class_method') score += SCORE_CLASS_METHOD;
158+
if (name === fullName) score += SCORE_TOP_LEVEL; // Top-level (Hash) > namespaced (Foo::Hash)
159+
if (nameLower === q.normalized) score += SCORE_EXACT_NAME; // Exact name match
170160
score -= name.length;
171161

172162
return score;

0 commit comments

Comments
 (0)