Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md

FSearch

Whole-disk file search for macOS: names in about 0.1 ms, typo-tolerant, plus indexed search inside files. A CLI with a small daemon, or a Rust crate.

cargo build --release && ./target/release/fsearch install   # -> ~/.local/bin/fsearch
fsearch fsearch main              # find files by name
fsearch 'ext:rs grep:apply_dir'   # search inside files

Speed

M4 Max, 8.3M files on disk, vs the previous version (76d612f). Same results. Medians.

beforenow
find a file by name1.0 ms0.13 ms7.7×
typing a whole filename, all keystrokes23 ms3.0 ms7.5×
search inside files14 ms2.3 ms6.2×
slowest 10% inside files (Chromium)38 ms2.3 ms16×
CLI, launch to answer5.5 ms3.3 ms1.7×
first run, fully searchable101 s49 s2.1×
first run, peak memory1.2 GB0.9 GB
index on disk (Chromium)0.32 GB0.76 GB2.4× bigger

The index grew because each file carries a filter that lets search skip files without the text.

Queries

fsearch 'readme in:~/Developer'          # inside a folder
fsearch 'type:image size:>5mb mtime:<7d'
fsearch 'ext:rs regex:fn\s+\w+_dir'      # regex inside files
fsearch 'sym:apply_dir'                  # where it's defined

Words are fuzzy, and 5+ letter words forgive one typo (mian.rs finds main.rs). Also 'exact, ^prefix, suffix$ and !exclude. Filters: ext: type: kind: in: size: mtime: re: path: grep: regex: sym: limit:. Content search is smart-case.

Full Disk Access

From a terminal with Full Disk Access it indexes everything. As a login item (fsearch install --login), grant ~/.local/bin/fsearch access in System Settings > Privacy & Security, again after each rebuild. Without access it skips protected folders instead of prompting.

API

JSON lines over ~/Library/Application Support/FSearch/fsearch.sock, or fsearch stdio:

{"q": "fsearch main", "limit": 20}
{"op": "grep", "pattern": "apply_dir", "in": "~/Developer"}

Or link the crate:

let engine = fsearch::Engine::start(fsearch::Options { dir: fsearch::default_dir(&home), home: home.clone(), skip: None })?;
let hits = engine.search(&fsearch::Query::parse("fsearch main", &home)?)?;

An app and the CLI share one index: the first process owns it, the rest follow.

How it works

  • Crawls the disk once with getattrlistbulk, then follows FSEvents: changes show up in about 0.1 s, and a restart replays only what changed.
  • Names live in one mmap'd file, folder by folder, so in: is a range. A bitmap of each name's letters rules out most names before scoring.
  • Content search is a trigram index plus a per-file filter, so a search only reads files likely to match. Identical files are indexed once. Matches are read fresh from disk.

关于 About

Whole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep. ~1 ms over 8M files.

语言 Languages

Rust99.7%
Shell0.3%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
136
Total Commits
峰值: 136次/周
Less
More

核心贡献者 Contributors