Skip to content

Add file search: a Files section in root search and a Search Files view - #86

Open
Assem130 wants to merge 2 commits into
typecraft-dev:mainfrom
Assem130:pr/file-search
Open

Assem130 wants to merge 2 commits into
typecraft-dev:mainfrom
Assem130:pr/file-search

Conversation

@Assem130

@Assem130 Assem130 commented Nov 9, 2026 •

Copy link
Copy Markdown

Adds file search (SPEC §8.6). The change is QML and JS only and adds no dependencies.

What it adds

  • Files section in root search. After Results, root search lists up to 5 matching files and folders from the home folder. Each row shows the parent folders as the subtitle and the modified date on the right.
  • Search Files. A built-in command opens it, and so does a "Search All Files" action on file rows, which carries the query over. The view has a 40/60 list and detail pane. Before you type, it lists recently changed files. The pane previews images and the first 4000 characters of text and code files under 1 MB, then shows Name, Where, Type, Size and Modified.
  • Actions. Open File or Open Folder (↵), Show in Files (Ctrl ↵, runs nautilus --select), and Copy Path (Ctrl Shift C).
  • Learned ranking. Opening or showing a file records a frecency visit under file:<path>. Those files get a bonus of 15 × log10 of the frecency score, capped at 40.
  • omacast doctor reports whether fd is installed and how many files it listed.

How it works

  • There is no index and no watcher. When the launcher opens and the listing is more than 30 seconds old, fd and stat list $HOME with fixed arguments. On my machine this takes about 55 ms for about 25,000 entries. Omarchy installs fd in its base packages.
  • omacast matches the query in-process, so the query never reaches an argv (ground rule 6).
  • fd skips hidden and git-ignored paths. The listing also excludes node_modules, .venv, venv, __pycache__, site-packages, target, .cache and .git, for projects that are not git repositories.
  • Ranking puts an exact name first, then a name prefix, a word start, a match inside the name, and a match in the path only. Newer files win ties. Every query word must match, and at least one must match the name.
  • Open runs gio open instead of xdg-open. xdg-open starts a Terminal=true default such as nvim without a terminal, so the file never appears. gio opens it in a terminal and picks the same app as a double-click in Files.
  • All file text in the UI uses Text.PlainText.

SPEC §8.6 planned a Rust indexer with SQLite and inotify. I noted the change of plan in SPEC §8.6 and in the CLAUDE.md status.

Related fix

Commands or the file listing can arrive after the first search answer, for example right after a reload. The selection now moves to the first row in that case, unless the user moved it. Before this change, a fast ↵ could land on the Google fallback.

Testing

  • node --test tests/*.test.js passes all 151 tests, including 16 new file-search tests with expected values worked out by hand.
  • omarchy plugin validate . passes.
  • I tested on the live launcher (Omarchy 4.5.0, Hyprland 0.56). I checked the Files section and its selection, opening a Markdown file, a plain text file in nvim and an image, Show in Files, Copy Path, and empty queries. In the Search Files view I checked all three preview kinds, carrying the query over, and the ranking after opening a file, also after a reload.

A Files section after Results lists files and folders from the home
directory that match the query. fd lists the home directory with fixed
arguments when the launcher opens (about 55 ms for 25k entries); the
query is matched in-process, so it never reaches an argv.

- core/FileSearch.js: listing parser, ranking (exact name, prefix, word
  start, substring, path), recency tie-break, glyphs, breadcrumbs, dates
- services/FileIndex.qml: fd + stat listing, default excludes for
  node_modules, virtualenvs, caches and build output
- Actions: Open File (gio open, so terminal apps such as nvim get a
  terminal), Show in Files, Copy Path (Ctrl+Shift+C)
- The selection follows the first file when the listing arrives after
  the first answer
- Search Files: a built-in command and a "Search All Files" action on
  file rows (carries the query). A 40/60 list and detail pane; before
  typing it lists recently changed files. The pane previews images and
  the head of text and code files (watched for edits), then Name,
  Where, Type, Size and Modified.
- Files opened or shown from omacast get a capped frecency bonus
  (15 x log10(score), max 40), stored like app visits.
- Copy Path answers Ctrl+Shift+C.
- When commands load after the first answer (right after a reload),
  the selection moves to the first row unless the user moved it, so a
  fast Enter no longer lands on a web fallback.
- omacast doctor reports fd and the listing size.
- README, SPEC 8.6 and CLAUDE.md status describe the design.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant