Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/local-search-neo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "local-search-neo",
"version": "1.0.0",
"version": "1.0.1",
"description": "借助 Everything 来进行文件搜索",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion plugins/local-search-neo/public/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"author": "the_tree",
"title": "本地搜索Neo",
"description": "借助 Everything 来进行文件搜索",
"version": "1.0.0",
"version": "1.0.1",
"main": "index.html",
"preload": "preload/services.js",
"logo": "logo.png",
Expand Down
42 changes: 31 additions & 11 deletions plugins/local-search-neo/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { onMounted } from "vue";
import Finder from "./Finder/index.vue";
import { useFinderEnterAction } from "./Finder/composables/useFinderEnterAction";
import { getFileIconDataUrl, warmUpFileIconCache } from "./Finder/core/fileIconCache";
import { DEFAULT_CATEGORIES, buildEverythingQuery } from "./Finder/core/finderLogic";
import {
DEFAULT_CATEGORIES,
buildEverythingQuery,
mergeResultsByMatchPathPriority,
} from "./Finder/core/finderLogic";
import { useFinderCategories } from "./Finder/composables/useFinderCategories";
import { usePersistStorage } from "./Finder/composables/usePersistStorage";
import { useSubInput } from "./Finder/composables/useSubInput";
Expand Down Expand Up @@ -47,23 +51,39 @@ onMounted(() => {
try {
if (!window.services.everything.isAvailable()) return [];
if (window.services.everything.getStartupStatus().state !== "ready") return [];
const result = window.services.everything.query(
const nameResult = window.services.everything.query(
everythingQuery,
MAIN_PUSH_RESULT_LIMIT,
"modified-desc",
matchPathEnabled.value,
false,
);
const items: MainPushSearchResult[] = result.items.map((item) => ({
title: item.path ?? getParentPath(item.fullPath),
text: item.name,
icon: window.ztools.getFileIcon(item.fullPath),
fullPath: item.fullPath,
}));
const matchPathResult = matchPathEnabled.value
? window.services.everything.query(
everythingQuery,
MAIN_PUSH_RESULT_LIMIT,
"modified-desc",
true,
)
: undefined;

if (result.total > MAIN_PUSH_RESULT_LIMIT) {
const resultItems = matchPathResult
? mergeResultsByMatchPathPriority(nameResult.items, matchPathResult.items)
: nameResult.items;
const total = matchPathResult?.total ?? nameResult.total;

const items: MainPushSearchResult[] = resultItems
.slice(0, MAIN_PUSH_RESULT_LIMIT)
.map((item) => ({
title: item.path ?? (item.fullPath ? getParentPath(item.fullPath) : ""),
text: item.name,
icon: item.fullPath ? window.ztools.getFileIcon(item.fullPath) : undefined,
fullPath: item.fullPath,
}));

if (total > MAIN_PUSH_RESULT_LIMIT) {
items.pop();
items.push({
text: `共有${result.total}个结果,查看更多...`,
text: `共有${total}个结果,查看更多...`,
});
}

Expand Down
24 changes: 20 additions & 4 deletions plugins/local-search-neo/src/Finder/composables/useFinderSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
getNextSelectedPath,
getNextVisibleCount,
getRestoredSelectedPath,
mergeResultsByMatchPathPriority,
type FinderResult,
type FinderSortMode,
} from "../core/finderLogic";
Expand Down Expand Up @@ -76,14 +77,29 @@ export function useFinderSearch({
visibleCount.value = pageSize;

try {
const result = window.services.everything.query(
const nameResult = window.services.everything.query(
everythingQuery,
maxResults,
currentSortMode,
currentMatchPathEnabled,
false,
);
results.value = result.items;
everythingTotal.value = result.total;

if (currentMatchPathEnabled) {
const matchPathResult = window.services.everything.query(
everythingQuery,
maxResults,
currentSortMode,
true,
);
results.value = mergeResultsByMatchPathPriority(
nameResult.items,
matchPathResult.items,
).slice(0, maxResults);
everythingTotal.value = matchPathResult.total;
} else {
results.value = nameResult.items;
everythingTotal.value = nameResult.total;
}
updateResultStatus();
restoreSelection(options);
} catch (error: unknown) {
Expand Down
11 changes: 1 addition & 10 deletions plugins/local-search-neo/src/Finder/composables/useSubInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export function useSubInput({ onInput, placeholder = "全盘搜索" }: UseSubInp
if (onInput) {
inputListeners.delete(onInput);
}
disposeSubInput();
});

function bindSubInput() {
Expand All @@ -46,6 +45,7 @@ export function useSubInput({ onInput, placeholder = "全盘搜索" }: UseSubInp
subInputReady = true;
}

/** 当非用户操作需要修改子输入框的值, 不触发重新搜索 */
function syncSubInputValue() {
if (!subInputReady) return;
programmaticInputValue = queryText.value;
Expand All @@ -56,19 +56,10 @@ export function useSubInput({ onInput, placeholder = "全盘搜索" }: UseSubInp
window.ztools.subInputFocus();
}

function disposeSubInput() {
if (!subInputReady) return;

window.ztools.removeSubInput();
subInputReady = false;
programmaticInputValue = undefined;
}

return {
bindSubInput,
syncSubInputValue,
focusSubInput,
disposeSubInput,
};
}

Expand Down
25 changes: 25 additions & 0 deletions plugins/local-search-neo/src/Finder/core/finderLogic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
isPdfPreviewCandidate,
isTextPreviewCandidate,
isVideoPreviewCandidate,
mergeResultsByMatchPathPriority,
type FinderCategory,
type FinderResult,
} from "./finderLogic";
Expand Down Expand Up @@ -105,6 +106,30 @@ test("getRestoredSelectedPath keeps existing visible selection or picks sorted f
assert.equal(getRestoredSelectedPath([], "D:\\missing.txt"), "");
});

test("mergeResultsByMatchPathPriority keeps name matches first and removes duplicates", () => {
const nameResults: FinderResult[] = [
{ name: "name-a.txt", path: "C:\\demo", fullPath: "C:\\demo\\name-a.txt" },
{ name: "shared.txt", path: "C:\\demo", fullPath: "C:\\demo\\shared.txt" },
{ name: "name-b.txt", path: "D:\\demo", fullPath: "D:\\demo\\name-b.txt" },
];
const matchPathResults: FinderResult[] = [
{ name: "shared.txt", path: "C:\\demo", fullPath: "c:\\demo\\shared.txt" },
{ name: "path-a.txt", path: "C:\\demo", fullPath: "C:\\demo\\path-a.txt" },
{ name: "path-b.txt", path: "D:\\demo", fullPath: "D:\\demo\\path-b.txt" },
];

assert.deepEqual(
mergeResultsByMatchPathPriority(nameResults, matchPathResults).map((item) => item.fullPath),
[
"C:\\demo\\name-a.txt",
"C:\\demo\\shared.txt",
"D:\\demo\\name-b.txt",
"C:\\demo\\path-a.txt",
"D:\\demo\\path-b.txt",
],
);
});

test("preview candidate helpers detect supported file types", () => {
assert.equal(isTextPreviewCandidate({ name: "main.log", size: 1024 }), true);
assert.equal(isTextPreviewCandidate({ name: "notes.md", size: 1024 }), true);
Expand Down
21 changes: 21 additions & 0 deletions plugins/local-search-neo/src/Finder/core/finderLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,23 @@ export function getRestoredSelectedPath(results: FinderResult[], currentPath: st
return results[0]?.fullPath ?? "";
}

export function mergeResultsByMatchPathPriority<
T extends Pick<FinderResult, "name" | "path" | "fullPath">,
>(nameResults: T[], matchPathResults: T[]): T[] {
const seen = new Set<string>();
const merged: T[] = [];

for (const item of [...nameResults, ...matchPathResults]) {
const key = getResultDedupeKey(item);
if (seen.has(key)) continue;

seen.add(key);
merged.push(item);
}

return merged;
}

export function isImagePreviewCandidate(
file: Pick<FinderResult, "name" | "extension" | "isDirectory">,
): boolean {
Expand Down Expand Up @@ -265,6 +282,10 @@ export function formatBytes(bytes?: number): string {
return `${formatNumber(value)} ${units[unitIndex]}`;
}

function getResultDedupeKey(item: Pick<FinderResult, "name" | "path" | "fullPath">): string {
return (item.fullPath || `${item.path ?? ""}\\${item.name}`).toLowerCase();
}

function normalizeCategoryRule(rule: string): string {
const trimmed = rule.trim();
if (!trimmed) return "";
Expand Down
2 changes: 0 additions & 2 deletions plugins/local-search-neo/src/Finder/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ watch(

onMounted(() => {
bindSubInput();
syncSubInputValue();
startEverythingStatusPolling();
void ensureEverythingReady();
window.ztools.onPluginOut(closeTransientState);
});
Expand Down
Loading