fix(search): match complete paths in file and project search
Treat slash-separated fragments as searchable text and use the same full-path fuzzy matcher for daemon results and remembered project paths.
This commit is contained in:
@@ -32,17 +32,30 @@ describe("buildWorkingDirectorySuggestions", () => {
|
||||
expect(results).toEqual(["/Users/me/projects/paseo-desktop"]);
|
||||
});
|
||||
|
||||
it("leaves path-query semantics to the daemon", () => {
|
||||
it("matches recommended paths using the complete path text", () => {
|
||||
const results = buildWorkingDirectorySuggestions({
|
||||
recommendedPaths: [
|
||||
"/Users/me/archive/projects/paseo-desktop",
|
||||
"/Users/me/projects/paseo-desktop",
|
||||
],
|
||||
serverPaths: [],
|
||||
query: "~/projects/pso",
|
||||
query: "projects/pso",
|
||||
});
|
||||
|
||||
expect(results).toEqual([]);
|
||||
expect(results).toEqual([
|
||||
"/Users/me/archive/projects/paseo-desktop",
|
||||
"/Users/me/projects/paseo-desktop",
|
||||
]);
|
||||
});
|
||||
|
||||
it("fuzzy-matches recommended paths using their full path", () => {
|
||||
const results = buildWorkingDirectorySuggestions({
|
||||
recommendedPaths: ["/Users/me/projects/blankpage/editor"],
|
||||
serverPaths: [],
|
||||
query: "blank page editor",
|
||||
});
|
||||
|
||||
expect(results).toEqual(["/Users/me/projects/blankpage/editor"]);
|
||||
});
|
||||
|
||||
it("treats '~' as an active query and includes daemon suggestions", () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { scoreMatch } from "@getpaseo/protocol/search/text-match";
|
||||
import { scorePathMatch } from "@getpaseo/protocol/search/text-match";
|
||||
|
||||
export interface BuildWorkingDirectorySuggestionsInput {
|
||||
recommendedPaths: string[];
|
||||
@@ -19,9 +19,8 @@ export function buildWorkingDirectorySuggestions(
|
||||
recommendedPathMatchesQuery(path, query),
|
||||
);
|
||||
|
||||
// The request owner correlates these results with the current query. The
|
||||
// daemon owns filesystem query parsing, filtering, and ranking; doing it
|
||||
// again here creates a second search implementation that can disagree.
|
||||
// Server paths are already ranked by the daemon. Recommended paths use the
|
||||
// same shared matcher, then keep their existing recommendation order.
|
||||
return uniquePaths([...matchingRecommended, ...input.serverPaths]);
|
||||
}
|
||||
|
||||
@@ -45,12 +44,8 @@ function recommendedPathMatchesQuery(path: string, query: string): boolean {
|
||||
if (["~", "~/"].includes(normalizedQuery)) {
|
||||
return true;
|
||||
}
|
||||
if (normalizedQuery.includes("/") || normalizedQuery.startsWith("~")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const basename = candidate.split("/").at(-1) ?? "";
|
||||
return candidate.includes(normalizedQuery) || scoreMatch(normalizedQuery, basename) !== null;
|
||||
return scorePathMatch(normalizedQuery, candidate) !== null;
|
||||
}
|
||||
|
||||
function normalizePath(value: string): string {
|
||||
|
||||
Reference in New Issue
Block a user