Z ZPI 文档 v0.3.8
介绍页

源码

packages/desktop/src/renderer/task-search-model.ts

typescript48 行查看原文
// Adapted from ZCode CommandCenterDialog (Apache-2.0).

import type { TaskSearchResult } from "../shared/bridge.ts";
import type { TaskSearchSnippet } from "../shared/task-search.ts";
import type { CommandCenterSearchScope } from "./task-search-history.ts";
export const searchScopePrefix = (scope: CommandCenterSearchScope) =>
  ({ all: "", commands: ">", conversations: "#", files: "@" })[scope];
export function resolveSearchScope(raw: string) {
  const trimmed = raw.trimStart();
  const prefixes: Partial<Record<string, CommandCenterSearchScope>> = {
    ">": "commands",
    "#": "conversations",
    "@": "files",
  };
  const scope = prefixes[trimmed[0]];
  return { query: scope ? trimmed.slice(1).trimStart() : raw.trim(), scope, explicit: Boolean(scope) };
}
export interface TaskSearchRow {
  key: string;
  task: TaskSearchResult;
  snippet?: TaskSearchSnippet;
}
export function taskSearchRows(tasks: readonly TaskSearchResult[], query: string) {
  const byId = new Map<string, TaskSearchResult>();
  for (const task of tasks) {
    const previous = byId.get(task.id);
    byId.set(task.id, previous ? { ...previous, snippets: [...previous.snippets, ...task.snippets] } : task);
  }
  return [...byId.values()].flatMap<TaskSearchRow>((task) => {
    const seen = new Set<string>();
    const snippets = query
      ? task.snippets.filter((snippet) => {
          const key = snippet.text
            .replace(/^\.{3}|\.{3}$/g, "")
            .replace(/\s+/g, " ")
            .trim()
            .toLocaleLowerCase();
          if (!key || seen.has(key)) return false;
          seen.add(key);
          return true;
        })
      : [];
    return snippets.length
      ? snippets.map((snippet, index) => ({ key: `${task.id}:${index}`, task, snippet }))
      : [{ key: task.id, task, snippet: undefined }];
  });
}