perf(filesearch): make file search opt-in and bound the fd walk

File search shelled out to `fd`/`locate` on every auto-mode keystroke,
walking $HOME and serialising behind a single daemon connection — observed
0.9–1.3s per keystroke, stalling every other provider's results. Gate it
behind explicit intent and bound the walk.

- DynamicProvider::runs_in_auto_mode() (default true); filesearch returns
  false, so it only runs when its `:file` prefix is active — never on a
  bare auto-mode query
- route `/` as a `:file` prefix alias in parse_query (identical ParsedQuery)
- drop the colon-less `file `/`find ` auto-triggers; `:file` / `/` cover it
  (also fixes `:file find me` searching for "me")
- bound fd: --max-depth, --exclude .git/node_modules/target/.cache,
  20 results, 750ms kill-timeout (spawn + drained stdout + reap)
- configurable providers.filesearch_roots (TOML + owlry.set; `~/` expanded,
  non-existent entries dropped); empty searches $HOME

Auto-mode typing drops from up to 1.3s to ~2–20ms; file search stays one
keystroke away.
This commit is contained in:
2026-06-01 16:55:31 +02:00
parent 5ae5bb8b87
commit ffa82bfed8
10 changed files with 417 additions and 66 deletions
+5
View File
@@ -33,6 +33,11 @@ owlry.set {
search_engine = "duckduckgo", -- google | duckduckgo | bing |
-- startpage | searxng | brave |
-- ecosia, or a custom "{query}" URL.
-- Root dirs for file search (the :file prefix or the / alias). "~/" is
-- expanded; non-existent entries are dropped. Empty (the default) searches
-- $HOME. File search is opt-in only — it never runs on a bare query.
-- filesearch_roots = { "~/Documents", "~/code" },
}
-- ──────────────────────────────────────────────────────────────────────