fix(command-palette): match file results against the full relative path
Cmd+P scored server file hits by basename only, so a query like "solo-is-a" returned nothing for solo-is-a-team-size/index.md. Score by relativePath and widen the server candidate limit to 40 so client-side reranking has enough to work with.
This commit is contained in:
@@ -352,7 +352,7 @@ export const CommandPalette: React.FC = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
void searchFiles(currentRoot, trimmedQuery, 10, { type: 'file' })
|
void searchFiles(currentRoot, trimmedQuery, 40, { type: 'file' })
|
||||||
.then((results) => {
|
.then((results) => {
|
||||||
if (cancelled) return;
|
if (cancelled) return;
|
||||||
setFileResults(
|
setFileResults(
|
||||||
|
|||||||
@@ -16,4 +16,27 @@ describe('commandPaletteFilesState', () => {
|
|||||||
expect(scoreCommandPaletteFiles(fileResults, 'alpha', freshKey, staleKey)).toEqual([]);
|
expect(scoreCommandPaletteFiles(fileResults, 'alpha', freshKey, staleKey)).toEqual([]);
|
||||||
expect(scoreCommandPaletteFiles(fileResults, 'alpha', freshKey, freshKey)).toHaveLength(1);
|
expect(scoreCommandPaletteFiles(fileResults, 'alpha', freshKey, freshKey)).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('matches directory segments of the relative path, not just the basename', () => {
|
||||||
|
const fileResults = [
|
||||||
|
{ name: 'index.md', path: '/kb/solo-is-a-team-size/index.md', relativePath: 'solo-is-a-team-size/index.md' },
|
||||||
|
{ name: 'index.md', path: '/kb/software-developer/index.md', relativePath: 'software-developer/index.md' },
|
||||||
|
];
|
||||||
|
const key = buildCommandPaletteFileSearchKey('/kb', 'solo-is-a');
|
||||||
|
|
||||||
|
const scored = scoreCommandPaletteFiles(fileResults, 'solo-is-a', key, key);
|
||||||
|
expect(scored).toHaveLength(1);
|
||||||
|
expect(scored[0].item.relativePath).toBe('solo-is-a-team-size/index.md');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ranks prefix path matches above later substring matches', () => {
|
||||||
|
const fileResults = [
|
||||||
|
{ name: 'index.md', path: '/kb/notes/solo/index.md', relativePath: 'notes/solo/index.md' },
|
||||||
|
{ name: 'index.md', path: '/kb/solo-is-a-team-size/index.md', relativePath: 'solo-is-a-team-size/index.md' },
|
||||||
|
];
|
||||||
|
const key = buildCommandPaletteFileSearchKey('/kb', 'solo');
|
||||||
|
|
||||||
|
const scored = scoreCommandPaletteFiles(fileResults, 'solo', key, key);
|
||||||
|
expect(scored[0].item.relativePath).toBe('solo-is-a-team-size/index.md');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const buildCommandPaletteFileSearchKey = (
|
|||||||
return JSON.stringify([currentRoot, trimmedQuery]);
|
return JSON.stringify([currentRoot, trimmedQuery]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const scoreCommandPaletteFiles = <T extends { name: string }>(
|
export const scoreCommandPaletteFiles = <T extends { name: string; relativePath: string }>(
|
||||||
fileResults: T[],
|
fileResults: T[],
|
||||||
trimmedQuery: string,
|
trimmedQuery: string,
|
||||||
fileSearchKey: string,
|
fileSearchKey: string,
|
||||||
@@ -21,7 +21,9 @@ export const scoreCommandPaletteFiles = <T extends { name: string }>(
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return scoreByFuzzyQuery(fileResults, trimmedQuery, (file) => file.name, {
|
// Score against the full relative path: queries like "solo-is-a" must match
|
||||||
|
// solo-is-a-team-size/index.md even though the basename is just index.md.
|
||||||
|
return scoreByFuzzyQuery(fileResults, trimmedQuery, (file) => file.relativePath || file.name, {
|
||||||
limit: 10,
|
limit: 10,
|
||||||
threshold: 0.4,
|
threshold: 0.4,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user