Repository navigation
Expand file tree
/
Copy pathsearch-core.js
More file actions
30 lines (30 loc) · 1.53 KB
/
Copy pathsearch-core.js
File metadata and controls
30 lines (30 loc) · 1.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* Shared search — used by the main window and quick search.
Tiered ranking: exact > starts-with > contains-all-words > synonym matches.
Always scans every set so no direct match is lost; caps each tier separately. */
function searchIcons(sets, rawQuery, maxResults) {
const raw = rawQuery.trim().toLowerCase();
if (!raw) return [];
const tokens = raw.split(/[\s_-]+/).filter(Boolean);
const joined = tokens.join('-');
const groups = tokens.map((t) => [t, ...(typeof SYN_LOOKUP !== 'undefined' && SYN_LOOKUP[t] ? SYN_LOOKUP[t] : [])]);
const hasSyns = groups.some((g) => g.length > 1);
const CAP = { starts: 2000, contains: 2500, related: 1000 };
const exact = [], starts = [], contains = [], related = [];
for (const s of sets) {
for (const name of s.icons) {
if (name === joined) exact.push({ prefix: s.prefix, name });
else if (name.startsWith(joined)) {
if (starts.length < CAP.starts) starts.push({ prefix: s.prefix, name });
} else if (tokens.every((t) => name.includes(t))) {
if (contains.length < CAP.contains) contains.push({ prefix: s.prefix, name });
} else if (hasSyns && related.length < CAP.related
&& groups.every((g) => g.some((v) => name.includes(v)))) {
related.push({ prefix: s.prefix, name });
}
}
}
starts.sort((a, b) => a.name.length - b.name.length);
contains.sort((a, b) => a.name.length - b.name.length);
related.sort((a, b) => a.name.length - b.name.length);
return [...exact, ...starts, ...contains, ...related].slice(0, maxResults);
}