@hienlh/ppm 0.11.11 → 0.11.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/web/assets/{audio-preview-DBoohjr_.js → audio-preview-D8nR9F8d.js} +1 -1
- package/dist/web/assets/{chat-tab-Bw-y-XyO.js → chat-tab-yxo8oBYc.js} +3 -3
- package/dist/web/assets/{code-editor-CsgU4_v0.js → code-editor-CKcPOXZV.js} +2 -2
- package/dist/web/assets/{conflict-editor-77mY0l5p.js → conflict-editor-DtzPzxR5.js} +1 -1
- package/dist/web/assets/{database-viewer-BHlWYrEW.js → database-viewer-DeiJYxBj.js} +1 -1
- package/dist/web/assets/{diff-viewer-BLBnf1k7.js → diff-viewer-Dve9ga_f.js} +1 -1
- package/dist/web/assets/{extension-webview-BBiDp-Dm.js → extension-webview-DrL4qHNy.js} +1 -1
- package/dist/web/assets/{image-preview-o3dt-W4e.js → image-preview-D3IgZDRo.js} +1 -1
- package/dist/web/assets/index-8Mwobh7l.js +23 -0
- package/dist/web/assets/{markdown-renderer-DauR_bTH.js → markdown-renderer-zaluanbN.js} +1 -1
- package/dist/web/assets/{pdf-preview-DWk-mv_p.js → pdf-preview-Yty6yXJU.js} +1 -1
- package/dist/web/assets/{port-forwarding-tab-CnNHiV1J.js → port-forwarding-tab-Ddlryv9D.js} +1 -1
- package/dist/web/assets/{postgres-viewer-CYP0QhAp.js → postgres-viewer-CUFg5d8S.js} +1 -1
- package/dist/web/assets/{settings-tab-BIVMWGLW.js → settings-tab-DIJMW_ZS.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-BfhYqGGK.js → sqlite-viewer-BA2uk_fo.js} +1 -1
- package/dist/web/assets/{terminal-tab-CsUkjfGm.js → terminal-tab-Bm0P3LZ7.js} +1 -1
- package/dist/web/assets/{video-preview-M0cH5kLT.js → video-preview-B2VaDLhw.js} +1 -1
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/src/web/components/layout/command-palette.tsx +8 -13
- package/src/web/lib/score-file-search.ts +90 -0
- package/dist/web/assets/index-Jmzyq_sm.js +0 -23
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File search scoring for command palette.
|
|
3
|
+
* Lower score = better match. Returns null if no match.
|
|
4
|
+
*
|
|
5
|
+
* Tiers: exact filename(0) > filename prefix(1) > filename contains(2)
|
|
6
|
+
* > path contains(3) > fuzzy filename(4) > fuzzy path(5)
|
|
7
|
+
*
|
|
8
|
+
* Tie-breakers: shorter filename, fewer path segments.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface FileSearchScore {
|
|
12
|
+
/** 0-5, lower = better tier */
|
|
13
|
+
tier: number;
|
|
14
|
+
/** Position of substring match, or fuzzy gap penalty */
|
|
15
|
+
offset: number;
|
|
16
|
+
/** Candidate filename length (shorter = better) */
|
|
17
|
+
nameLen: number;
|
|
18
|
+
/** Number of path segments (fewer = more prominent) */
|
|
19
|
+
depth: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Extract filename from a path */
|
|
23
|
+
function getFilename(path: string): string {
|
|
24
|
+
const i = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
25
|
+
return i >= 0 ? path.slice(i + 1) : path;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Subsequence fuzzy match — returns gap penalty (sum of distances between
|
|
30
|
+
* consecutive matched chars). Lower = more consecutive. Returns -1 if no match.
|
|
31
|
+
*/
|
|
32
|
+
function fuzzyGap(query: string, text: string): number {
|
|
33
|
+
let ti = 0;
|
|
34
|
+
let gap = 0;
|
|
35
|
+
let lastMatch = -1;
|
|
36
|
+
for (let qi = 0; qi < query.length; qi++) {
|
|
37
|
+
ti = text.indexOf(query[qi]!, ti);
|
|
38
|
+
if (ti === -1) return -1;
|
|
39
|
+
if (lastMatch >= 0) gap += ti - lastMatch - 1;
|
|
40
|
+
lastMatch = ti;
|
|
41
|
+
ti++;
|
|
42
|
+
}
|
|
43
|
+
return gap;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function scoreFileSearch(
|
|
47
|
+
query: string,
|
|
48
|
+
label: string,
|
|
49
|
+
path: string,
|
|
50
|
+
): FileSearchScore | null {
|
|
51
|
+
const q = query.toLowerCase();
|
|
52
|
+
const nameLower = label.toLowerCase();
|
|
53
|
+
const pathLower = path.toLowerCase();
|
|
54
|
+
const filename = getFilename(pathLower);
|
|
55
|
+
const depth = path.split("/").length;
|
|
56
|
+
|
|
57
|
+
// Tier 0: exact filename match
|
|
58
|
+
if (filename === q) return { tier: 0, offset: 0, nameLen: label.length, depth };
|
|
59
|
+
|
|
60
|
+
// Tier 1: filename starts with query
|
|
61
|
+
if (filename.startsWith(q)) return { tier: 1, offset: 0, nameLen: label.length, depth };
|
|
62
|
+
|
|
63
|
+
// Tier 2: filename contains query as substring
|
|
64
|
+
const fnIdx = filename.indexOf(q);
|
|
65
|
+
if (fnIdx >= 0) return { tier: 2, offset: fnIdx, nameLen: label.length, depth };
|
|
66
|
+
|
|
67
|
+
// Tier 3: full path contains query as substring
|
|
68
|
+
const pathIdx = pathLower.indexOf(q);
|
|
69
|
+
if (pathIdx >= 0) return { tier: 3, offset: pathIdx, nameLen: label.length, depth };
|
|
70
|
+
|
|
71
|
+
// Tier 4: fuzzy match on filename
|
|
72
|
+
const fnGap = fuzzyGap(q, filename);
|
|
73
|
+
if (fnGap >= 0) return { tier: 4, offset: fnGap, nameLen: label.length, depth };
|
|
74
|
+
|
|
75
|
+
// Tier 5: fuzzy match on full path
|
|
76
|
+
const pathGap = fuzzyGap(q, pathLower);
|
|
77
|
+
if (pathGap >= 0) return { tier: 5, offset: pathGap, nameLen: label.length, depth };
|
|
78
|
+
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Compare two scores — for Array.sort (ascending = best first) */
|
|
83
|
+
export function compareScores(a: FileSearchScore, b: FileSearchScore): number {
|
|
84
|
+
return (
|
|
85
|
+
a.tier - b.tier ||
|
|
86
|
+
a.offset - b.offset ||
|
|
87
|
+
a.nameLen - b.nameLen ||
|
|
88
|
+
a.depth - b.depth
|
|
89
|
+
);
|
|
90
|
+
}
|