Skip to content

Commit 326f938

Browse files
lifthrasiiralexcrichton
authored andcommitted
rustdoc: Better sorting criteria for searching.
This essentially rewrites the sorting algorithm, which relied on the implementation-defined handling of non-consistent sorting function (cf. ECMA-262 5th edition, section 15.4.4.11) and was also a bit inefficient. The new criteria expands the prior criteria while adding these ones: - The current crate is always preferred over other crates. (Closes #13178) - An item with a description is preferred over one without it, if item names match. This is a heuristic assuming that the documented item is more likely to be relevant. - An item with no literal occurrence of search query is handled correctly.
1 parent ea5d908 commit 326f938

File tree

1 file changed

+52
-51
lines changed

1 file changed

+52
-51
lines changed

src/librustdoc/html/static/main.js

+52-51
Original file line numberDiff line numberDiff line change
@@ -189,67 +189,68 @@
189189
for (var i = 0; i < nresults; i += 1) {
190190
results[i].word = searchWords[results[i].id];
191191
results[i].item = searchIndex[results[i].id] || {};
192-
results[i].ty = results[i].item.ty;
193-
results[i].path = results[i].item.path;
194192
}
195193
// if there are no results then return to default and fail
196194
if (results.length === 0) {
197195
return [];
198196
}
199197

200-
// sort by exact match
201-
results.sort(function search_complete_sort0(aaa, bbb) {
202-
if (aaa.word === valLower &&
203-
bbb.word !== valLower) {
204-
return 1;
205-
}
206-
});
207-
// first sorting attempt
208-
// sort by item name length
209-
results.sort(function search_complete_sort1(aaa, bbb) {
210-
if (aaa.word.length > bbb.word.length) {
211-
return 1;
212-
}
198+
results.sort(function(aaa, bbb) {
199+
var a, b;
200+
201+
// sort by crate (non-current crate goes later)
202+
a = (aaa.item.crate !== window.currentCrate);
203+
b = (bbb.item.crate !== window.currentCrate);
204+
if (a !== b) return a - b;
205+
206+
// sort by exact match (mismatch goes later)
207+
a = (aaa.word !== valLower);
208+
b = (bbb.word !== valLower);
209+
if (a !== b) return a - b;
210+
211+
// sort by item name length (longer goes later)
212+
a = aaa.word.length;
213+
b = bbb.word.length;
214+
if (a !== b) return a - b;
215+
216+
// sort by item name (lexicographically larger goes later)
217+
a = aaa.word;
218+
b = bbb.word;
219+
if (a !== b) return (a > b ? +1 : -1);
220+
221+
// sort by index of keyword in item name (no literal occurrence goes later)
222+
a = (aaa.index < 0);
223+
b = (bbb.index < 0);
224+
if (a !== b) return a - b;
225+
// (later literal occurrence, if any, goes later)
226+
a = aaa.index;
227+
b = bbb.index;
228+
if (a !== b) return a - b;
229+
230+
// sort by description (no description goes later)
231+
a = (aaa.item.desc === '');
232+
b = (bbb.item.desc === '');
233+
if (a !== b) return a - b;
234+
235+
// sort by type (later occurrence in `itemTypes` goes later)
236+
a = aaa.item.ty;
237+
b = bbb.item.ty;
238+
if (a !== b) return a - b;
239+
240+
// sort by path (lexicographically larger goes later)
241+
a = aaa.item.path;
242+
b = bbb.item.path;
243+
if (a !== b) return (a > b ? +1 : -1);
244+
245+
// que sera, sera
246+
return 0;
213247
});
214-
// second sorting attempt
215-
// sort by item name
216-
results.sort(function search_complete_sort1(aaa, bbb) {
217-
if (aaa.word.length === bbb.word.length &&
218-
aaa.word > bbb.word) {
219-
return 1;
220-
}
221-
});
222-
// third sorting attempt
223-
// sort by index of keyword in item name
224-
if (results[0].index !== -1) {
225-
results.sort(function search_complete_sort1(aaa, bbb) {
226-
if (aaa.index > bbb.index && bbb.index === 0) {
227-
return 1;
228-
}
229-
});
230-
}
231-
// fourth sorting attempt
232-
// sort by type
233-
results.sort(function search_complete_sort3(aaa, bbb) {
234-
if (aaa.word === bbb.word &&
235-
aaa.ty > bbb.ty) {
236-
return 1;
237-
}
238-
});
239-
// fifth sorting attempt
240-
// sort by path
241-
results.sort(function search_complete_sort4(aaa, bbb) {
242-
if (aaa.word === bbb.word &&
243-
aaa.ty === bbb.ty && aaa.path > bbb.path) {
244-
return 1;
245-
}
246-
});
247-
// sixth sorting attempt
248+
248249
// remove duplicates, according to the data provided
249250
for (var i = results.length - 1; i > 0; i -= 1) {
250251
if (results[i].word === results[i - 1].word &&
251-
results[i].ty === results[i - 1].ty &&
252-
results[i].path === results[i - 1].path)
252+
results[i].item.ty === results[i - 1].item.ty &&
253+
results[i].item.path === results[i - 1].item.path)
253254
{
254255
results[i].id = -1;
255256
}

0 commit comments

Comments
 (0)